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

时间:2009-08-17 02:12:36

标签: python dictionary

我想做类似的事情:

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

if ("foo","bar") in foo:
    #do stuff

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

20 个答案:

答案 0 :(得分:302)

嗯,你可以这样做:

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

答案 1 :(得分:107)

if set(("foo", "bar")) <= set(myDict): ...

答案 2 :(得分:35)

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

答案 3 :(得分:25)

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

if {'foo', 'bar'} <= set(some_dict):
    pass

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

答案 4 :(得分:21)

使用 sets

if set(("foo", "bar")).issubset(foo):
    #do stuff

可替换地:

if set(("foo", "bar")) <= set(foo):
    #do stuff

答案 5 :(得分:7)

这个怎么样:

if all(key in foo for key in ["foo","bar"]):
    # do stuff
    pass

答案 6 :(得分:7)

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

虽然它有更多字符,但按照Karl Voigtland的建议使用<=的答案更容易理解。由于该方法可以使用字典作为参数,因此一个简短易懂的解决方案是:

issubset()

我想用foo = {'foo': 1, 'zip': 2, 'zam': 3, 'bar': 4} if set(('foo', 'bar')).issubset(foo): #do stuff 代替{'foo', 'bar'},因为它更短。然而,这并不是那么容易理解,我认为括号太容易被混淆为字典。

答案 7 :(得分:4)

Alex Martelli的解决方案set(queries) <= set(my_dict)是最短的代码,但可能不是最快的。假设Q = len(查询)和D = len(my_dict)。

这需要O(Q)+ O(D)来制作两个集合,然后(一个希望!)只有O(min(Q,D))来进行子集测试 - 当然假设Python集合查找是O(1) - 这是最坏的情况(当答案为真时)。

hughdbrown(et al?)all(k in my_dict for k in queries)的生成器解是O(Q)的最坏情况。

复杂因素:
(1)基于集合的小工具中的循环都是以C速度完成的,而基于任何小工具的循环都是字节码。
(2)任何基于任何小工具的调用者都可以使用任何失败概率的知识来相应地对查询项进行排序,而基于集合的小工具则不允许这样的控制。

与往常一样,如果速度很重要,那么在运营条件下进行基准测试是一个好主意。

答案 8 :(得分:4)

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

{'key_1', 'key_2', 'key_3'} <= set(my_dict)

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

{'key_1', 'key_2', 'key_3'} & set(my_dict)

答案 9 :(得分:3)

我认为这是最明智的选择。

{'key1','key2'} <= my_dict.keys()

答案 10 :(得分:1)

如果你想:

  • 也会获取密钥的值
  • 检查多个dictonary

然后:

from operator import itemgetter
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
keys = ("foo","bar") 
getter = itemgetter(*keys) # returns all values
try:
    values = getter(foo)
except KeyError:
    # not both keys exist
    pass

答案 11 :(得分:1)

不是说这不是你没想过的东西,但我发现最简单的东西通常是最好的:

if ("foo" in foo) and ("bar" in foo):
    # do stuff

答案 12 :(得分:1)

>>> if 'foo' in foo and 'bar' in foo:
...     print 'yes'
... 
yes

Jason,()在Python中不是必需的。

答案 13 :(得分:1)

如何使用lambda?

 if reduce( (lambda x, y: x and foo.has_key(y) ), [ True, "foo", "bar"] ): # do stuff

答案 14 :(得分:0)

您也可以使用.issubset()

>>> {"key1", "key2"}.issubset({"key1":1, "key2":2, "key3": 3})
True
>>> {"key4", "key2"}.issubset({"key1":1, "key2":2, "key3": 3})
False
>>>

答案 15 :(得分:0)

仅此而已,对于所有给定的选项,有两种易于理解的方法。因此,我的主要标准是拥有非常易读的代码,而不是异常快速的代码。为了使代码易于理解,我更喜欢给出可能性:

  • var <= var2.keys()
  • var.issubset(var2)

在下面的测试中,“ var <= var2.keys()”的执行速度更快,这一点我很喜欢。

import timeit

timeit.timeit('var <= var2.keys()', setup='var={"managed_ip", "hostname", "fqdn"}; var2= {"zone": "test-domain1.var23.com", "hostname": "bakje", "api_client_ip": "127.0.0.1", "request_data": "", "request_method": "GET", "request_url": "hvar2p://127.0.0.1:5000/test-domain1.var23.com/bakje", "utc_datetime": "04-Apr-2019 07:01:10", "fqdn": "bakje.test-domain1.var23.com"}; var={"managed_ip", "hostname", "fqdn"}')
0.1745898080000643

timeit.timeit('var.issubset(var2)', setup='var={"managed_ip", "hostname", "fqdn"}; var2= {"zone": "test-domain1.var23.com", "hostname": "bakje", "api_client_ip": "127.0.0.1", "request_data": "", "request_method": "GET", "request_url": "hvar2p://127.0.0.1:5000/test-domain1.var23.com/bakje", "utc_datetime": "04-Apr-2019 07:01:10", "fqdn": "bakje.test-domain1.var23.com"}; var={"managed_ip", "hostname", "fqdn"};')
0.2644960229999924

答案 16 :(得分:0)

在确定是否只有某些键匹配的情况下,此方法有效:

any_keys_i_seek = ["key1", "key2", "key3"]

if set(my_dict).intersection(any_keys_i_seek):
    # code_here
    pass

还有另一种方法来查找是否只有一些键匹配:

any_keys_i_seek = ["key1", "key2", "key3"]

if any_keys_i_seek & my_dict.keys():
    # code_here
    pass

答案 17 :(得分:0)

另一个用于检测所有键是否都在字典中的选项:

dict_to_test = { ... }  # dict
keys_sought = { "key_sought_1", "key_sought_2", "key_sought_3" }  # set

if keys_sought & dict_to_test.keys() == keys_sought: 
    # True -- dict_to_test contains all keys in keys_sought
    # code_here
    pass

答案 18 :(得分:0)

又短又甜

{"key1", "key2"} <= {*dict_name}

答案 19 :(得分:-4)

>>> ok
{'five': '5', 'two': '2', 'one': '1'}

>>> if ('two' and 'one' and 'five') in ok:
...   print "cool"
... 
cool

这似乎有效