【问题标题】:Python: Check if any list element is a key in a dictionaryPython:检查任何列表元素是否是字典中的键
【发布时间】:2011-11-03 06:35:40
【问题描述】:

给定以下代码

all_options = { "1": "/test/1", "2": "/test/2", "3": "/test/3" }
selected_options = [ "1", "3" ]

如何从 all_options 中获取键与 selected_options 中的条目匹配的条目?

我开始使用 List Comprehension,但我卡在最后一个子句:

final = ()
[ final.append(option) for option in all_options if ... ]

谢谢

【问题讨论】:

  • 那是使用列表推导的错误方式。您正在创建一个很大的 None 列表并将其丢弃。只需使用final = [...]

标签: python list search dictionary


【解决方案1】:

就这样?

>>> dict((option, all_options[option]) for option in selected_options if option in all_options)
{'1': '/test/1', '3': '/test/3'}

从 Python 2.7 和 3 开始,您可以使用dict comprehension 语法:

{option : all_options[option] for option in selected_options if option in all_options}

或者,如果您只想要这些值:

>>> [all_options[option] for option in selected_options if option in all_options]
['/test/1', '/test/3']

【讨论】:

  • 有没有办法让结果成为字典而不是列表?
  • 正要对此发表评论 :) 效果很好,谢谢
  • dict 版本中不需要列表推导,只需使用生成器表达式即可。
【解决方案2】:

请改用set()take advantage of the intersection operation

>>> final = set(all_options.keys()) & set(selected_options)
>>> print(final)
{'1', '3'}

上面只返回键,但 NullUserException 指出问题可能也需要值,使用 dict 理解:

>>> {x: all_options[x] for x in set(all_options.keys()) & set(selected_options)}
{'1': '/test/1', '3': '/test/3'}

为了完整起见,这里只是值:

>>> [all_options[x] for x in set(all_options.keys()) & set(select_options)]
['/test/1', '/test/3']

以下是错误的。使用 set() 会遍历两个列表,而不仅仅是一个。

假设选项变大,使用集合会更好。条件列表推导检查其中一个容器中的每个项目,但集合交集利用了 Python 出色的散列。甚至这里的列表理解也只在 all_options 中查找所需的键。

【讨论】:

  • 构建集合仍然需要对容器进行迭代 - 但这是对每个容器的一次迭代,而不是有效地迭代笛卡尔积。
  • 原来如此。没有这么想。尽管如此,-1 还是在我说之前出现了。
【解决方案3】:

如何从 all_options 中获取键与 selected_options 中的条目匹配的条目?

带着理解。我们有两种:列表推导式和生成器推导式。

请注意,这取决于“条目”的含义。如果您想要一个具有匹配键/值对的dict,那么您需要一个创建键/值对的理解,然后通过将其提供给dict 构造函数来使用它来创建一个dict。

有一个特殊的语法规则说,如果我们只用一个参数调用可调用的东西(比如类构造函数),并且该参数是生成器推导式,那么我们只需要一对括号(而不是二:一个调用函数,另一个将理解标记为理解)。这让我们可以写出看起来很自然的东西。

另一方面,如果你只想要一个list 的键,那么你可以只使用列表推导。 (您也可以将生成器理解传递给 list 构造函数。)

我开始使用列表理解的路径...

从根本上说,您对它们的工作方式有错误的想法。您不会使用它们重复执行某个操作;您可以使用它们重复计算结果。您不会在语句的第一部分进行append 调用,因为(a)理解已经为您构建序列,因此没有理由创建另一个要附加的空序列; (b) append 调用在执行附加后返回 None,因此您最终会得到一个 None 值列表,您随后会丢弃这些值。

列表推导式创造价值。生成器推导也会创建一个值,但它是一个生成器(因此您必须提取其值才能使用它们)。

那么,我们如何编写代码呢?

一个list 的键看起来像这样:对于dict 中的每个键(迭代dict 迭代它的键),我们想要那个键(没有修改) , 仅当密钥在我们的另一个 list 中时。也就是说,我们想要[key for key in all_options if key in selected_options]。这正是你用 Python 编写它的方式。一种语言几乎不能再自然地阅读,同时仍然是明确的。

键值对的dict 看起来像这样:对于dict 的键值对中的每个键值对,我们需要那个键值对,前提是键在我们的另一个list 中.我们想使用这些键值对创建dict,因此我们将理解包装在dict 构造函数中。为了从字典中获取键值对,我们遍历它的.items()。所以,我们想要一个由键和值构成的dict,用于原始dict 的项目中的每个键和值,其中键在另一个list 中。再说一次,这正是我们所写的:dict((key, value) for (key, value) in all_options if key in selected_options)

在最新版本的 Python 中,我们还可以使用“dict comprehension”,它基本上是语法糖,这样我们就可以编写看起来更像列表理解的东西。

【讨论】:

  • 感谢您的解释,现在这更有意义了。
【解决方案4】:

我不确定您要返回的确切内容,所以我提供了几个选择:

如果您尝试返回:['1', '3']

[option for option in all_options if option in selected_options]

如果您尝试返回:['/test/1', '/test/3']

[all_options[option] for option in all_options if option in selected_options]

【讨论】:

    【解决方案5】:
    [option for option in all_options if option in selected_options]
    

    您可能希望创建一个 setselected_options 并在有很多时使用它。

    【讨论】:

    • 嗯,我的印象是 OP 想要一个与我和 Johnsyweb 所写内容一致的答案,但我可能错了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多