如何在一次通过中检查多个键是否在dict中?

190 python dictionary

我想做的事情如下:

foo = {'foo':1,'zip':2,'zam':3,'bar':4}

if ("foo","bar") in foo:
    #do stuff
Run Code Online (Sandbox Code Playgroud)

如何检查'foo'和'bar'是否都在dict foo中?

hug*_*own 319

好吧,你可以这样做:

>>> if all (k in foo for k in ("foo","bar")):
...     print "They're there!"
...
They're there!
Run Code Online (Sandbox Code Playgroud)

  • +1,我比Greg的答案更喜欢这个,因为它更简洁,更快(不构建无关的临时列表,并充分利用短路). (9认同)
  • 我爱所有()和任何().他们使这么多算法变得更加清晰. (4认同)
  • 由于短路,这是一个很好的解决方案,特别是如果测试经常失败,除非你只需要创建一组感兴趣的键并多次检查它,在这种情况下`set`是优越的.像往常一样......测量它! - ) (4认同)

Ale*_*lli 112

if set(("foo", "bar")) <= set(myDict): ...
Run Code Online (Sandbox Code Playgroud)

  • `if {'foo','bar'} <= set(myDict):...` (27认同)
  • 在python 3中你可以说`set(("foo","bar"))<= myDict.keys()`它可以避免临时设置,因此更快.对于我的测试,当查询为10项时,它与使用all的速度大致相同.它随着查询变大而变慢. (16认同)
  • 对于任何想知道为什么这样做的人:运算符<=与使用.set issubset()方法相同:https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset (6认同)

Joh*_*ooy 36

3种替代方案的简单基准测试平台.

为D和Q输入您自己的值


>>> from timeit import Timer
>>> setup='''from random import randint as R;d=dict((str(R(0,1000000)),R(0,1000000)) for i in range(D));q=dict((str(R(0,1000000)),R(0,1000000)) for i in range(Q));print("looking for %s items in %s"%(len(q),len(d)))'''

>>> Timer('set(q) <= set(d)','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632499
0.28672504425048828

#This one only works for Python3
>>> Timer('set(q) <= d.keys()','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632084
2.5987625122070312e-05

>>> Timer('all(k in d for k in q)','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632219
1.1920928955078125e-05
Run Code Online (Sandbox Code Playgroud)

  • Python 2.7有`d.viewkeys()`来使`set(q)<= d.viewkeys()`. (3认同)
  • @IvanKharlamov,但在 Python2 中,它不返回与 `set(q) &lt;= ...` 兼容的对象 (3认同)

小智 29

您不必将左侧包裹在一组中.你可以这样做:

if {'foo', 'bar'} <= set(some_dict):
    pass
Run Code Online (Sandbox Code Playgroud)

这也比all(k in d...)解决方案更好.

  • 这也比all(k in d ...)解决方案表现更好.我建议这是一个编辑,但它被拒绝的理由是[更好地添加评论](http://stackoverflow.com/review/suggested-edits/6905833).所以这就是我这样做的 (2认同)

Kar*_*and 22

使用集合:

if set(("foo", "bar")).issubset(foo):
    #do stuff
Run Code Online (Sandbox Code Playgroud)

或者:

if set(("foo", "bar")) <= set(foo):
    #do stuff
Run Code Online (Sandbox Code Playgroud)

  • 我在回答中使用的 set(d) 就像 set(d.keys()) 但更快,更短,而且我会说在风格上更可取。 (2认同)

Sho*_*ura 11

我认为这是最聪明和最重要的。

{'key1','key2'} <= my_dict.keys()
Run Code Online (Sandbox Code Playgroud)


Gre*_*reg 9

这个怎么样:

if all(key in foo for key in ["foo","bar"]):
    # do stuff
    pass
Run Code Online (Sandbox Code Playgroud)

  • 事实上,不仅是不必要的,有害的,因为它们阻碍了"所有"的正常短路行为. (8认同)

L S*_*L S 7

虽然我喜欢Alex Martelli的回答,但对我来说它似乎并不像Pythonic.也就是说,我认为Pythonic的一个重要部分是易于理解的.有了这个目标,<=就不容易理解.

虽然它是更多的角色,但issubset()按照Karl Voigtland的回答使用更容易理解.由于该方法可以使用字典作为参数,因此一个简短易懂的解决方案是:

foo = {'foo': 1, 'zip': 2, 'zam': 3, 'bar': 4}

if set(('foo', 'bar')).issubset(foo):
    #do stuff
Run Code Online (Sandbox Code Playgroud)

我想用{'foo', 'bar'}它代替set(('foo', 'bar')),因为它更短.然而,这不是那么容易理解,我认为括号太容易被混淆为字典.

  • 一旦你明白它意味着什么,我认为这是可以理解的. (2认同)

Nav*_*ala 5

检查字典中是否存在所有键:

{'key_1', 'key_2', 'key_3'} <= set(my_dict)
Run Code Online (Sandbox Code Playgroud)

检查字典中是否存在一个或多个键:

{'key_1', 'key_2', 'key_3'} & set(my_dict)
Run Code Online (Sandbox Code Playgroud)