【问题标题】:python3 list comprehension using a dictionary doesn't always return the same list使用字典的python3列表理解并不总是返回相同的列表
【发布时间】:2018-06-02 22:58:26
【问题描述】:

编辑: 根据要求,这是我要解决的问题: 我在没有扩展名的目录中有文件。根据“文件”命令的输出,我想分配相应的扩展名。所以我的字典将可以在此输出中的字符串分配给扩展名(例如“ASCII”:“txt”),但不知道它是否是确切的输出。例如:

$ file my_file
myfile: ASCII text
# I want to change the extension of myfile to myfile.txt

这就是我编写的代码的目的,但也许有更好的解决方案

我有一个字符串字典,其中的键具有通用字符串:

MY_D = {
    "first_k": "first_v",
    "sec_k": "sec_v",
    "some_key_name_that_includes_others": "value1",
    "some_other_key": "value2",
    ...
    "last_k": "last_v"
    }

有时,如果搜索词在键中,我必须获取一个值。我使用此代码:

key_I_am_looking_for = "some"
value = list(v for k, v in MY_D.items() if value_I_am_looking_for in k)[-1]

但是当我要找的键出现在多个可能的键中时,我得到的值并不总是相同的,在这个例子中它可以是“value1”或“value2”。 我注意到返回的列表并不总是以相同的方式排序。

有没有一种方法可以让这个返回总是与匹配的最长键对应的值(这里是“value1”)?

【问题讨论】:

  • dict 在设计上是无序的,因此当调用MY_D.items() 时,无法保证您会按照插入它们的顺序获得这些项目。如果你想保留插入顺序,你应该考虑使用OrderedDict
  • 这对我来说像是一个XY problem 的问题。您所描述的内容还取决于 dict 的创建方式以及您使用的 Python 版本,因此我怀疑您是否会得到对这个问题有帮助的答案。您能否更新您的答案,描述您需要解决的实际问题?
  • 或者更新到python 3.6,这是有序的,现在字典保证将来保持插入顺序。
  • @MatiasCicero - 这不太正确。从 Python 3.6 开始,插入顺序保留在 CPython 中(但不能保证所有实现),从 Python3.7 开始,它甚至会得到保证。
  • @OliverBestwalter :明白,我试图在编辑中描述我的问题。

标签: python python-3.x list-comprehension


【解决方案1】:

直到 Python 3.7 的字典都按规范无序,这意味着代码不应依赖字典的内部顺序。

解决此问题的方法只是对您的 dict 交互的输出进行排序。在您的 sn-p 中,只需通过调用 sorted 将调用更改为 list 即可完成:

value = sorted(v for k, v in MY_D.items() if value_I_am_looking_for in k)[-1]

【讨论】:

  • 我明白这将如何解决我的问题,但它不会解决我的问题。我将编辑我的问题以使其更清晰,但我不希望代码只是输出相同的内容,我想控制它应该是哪个输出。
  • 什么会“解决你的问题”绝对是一个颠倒的字典,就像在另一个答案中一样。得到答案后不断更改问题并不能帮助您获得良好的体验。
【解决方案2】:

所有匹配中最长的键。使用 lambda 排序可能会有所帮助。

这会在列表列表中获取每个匹配项,并使用 sorted 和 key=lambda... 来确定每个列表中第一项的长度(即保存的键名)。它将最短的键名排序为最长的。获取最后一个列表和该列表的最后一项以获取 value1 的值。

MY_D = {
    "first_k": "first_v",
    "sec_k": "sec_v",
    "some_key_name_that_includes_others": "value1",
    "some_other_key": "value2",
    "last_k": "last_v"
    }

key_I_am_looking_for = "some"

# List of lists of matches.
value = list([k, v] for k, v in MY_D.items() if key_I_am_looking_for in k)

# Sort by index 0 of each inner list.
key_len = sorted(value, key=lambda l: len(l[0]))

# Last list is longest index 0 so get last item of that list.
print('longest:', key_len[-1][-1])

【讨论】:

    猜你喜欢
    • 2018-08-01
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2022-01-23
    相关资源
    最近更新 更多