python:我怎么检查多个键在字典中一次去?
我想做一些事情:
foo = {'foo':1,'zip':2,'zam':3,'bar':4} if ("foo","bar") in foo: #do stuff
我不确定它是否可能,但想知道。 🙂
那么,你可以这样做:
>>> if all (k in foo for k in ("foo","bar")): ... print "They're there!" ... They're there!
if set(("foo", "bar")) <= set(myDict): ...
简单的基准钻井平台的3个替代品。
为D和Qinput你自己的值
>>> 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
使用集合 :
if set(("foo", "bar")).issubset(foo): #do stuff
或者:
if set(("foo", "bar")) <= set(foo): #do stuff
您不必将左侧包裹在一个集合中。 你可以这样做:
if {'foo', 'bar'} <= set(some_dict): pass
这也比all(k in d...)
解决schemeperformance更好。
这个怎么样:
if all(key in foo for key in ["foo","bar"]): # do stuff pass
Alex Martelli的解决schemeset(queries) <= set(my_dict)
是最短的代码,但可能不是最快的。 假设Q = len(查询)和D = len(my_dict)。
这需要O(Q)+ O(D)做两个集合,然后(希望!)只有O(min(Q,D))做子集testing – 假设当然Python集合查找是O(1) – 这是最坏的情况(当答案是真的时)。
hughdbrown(et al?)的生成器解决scheme都是最差的O(Q)。
复杂的因素:
(1)基于集合的小工具中的循环全部以C速度完成,而基于任何的小工具循环遍历字节代码。
(2)任何基于小工具的调用者可能能够使用任何有关失败概率的知识来相应地sorting查询项目,而基于集合的小工具不允许这样的控制。
一如既往,如果速度很重要,在运营条件下进行基准testing是一个好主意。
虽然我喜欢亚历克斯·马尔泰利的回答,但对我来说这似乎不是Pythonic。 也就是说,我认为Pythonic的一个重要部分是容易理解的。 有了这个目标, <=
并不容易理解。
虽然它是更多的字符, issubset()
如Karl Voigtland的回答所build议的使用issubset()
更容易理解。 既然这个方法可以用字典作为参数,一个简短的,可以理解的解决scheme是:
foo = {'foo': 1, 'zip': 2, 'zam': 3, 'bar': 4} if set(('foo', 'bar')).issubset(foo): #do stuff
我想用{'foo', 'bar'}
代替set(('foo', 'bar'))
,因为它更短。 然而,这不是可以理解的,我认为大括号太容易混淆成字典。
如何使用lambda?
if reduce( (lambda x, y: x and foo.has_key(y) ), [ True, "foo", "bar"] ): # do stuff
如果您想要:
- 也获得键的值
- 检查多个词典
然后:
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
>>> if 'foo' in foo and 'bar' in foo: ... print 'yes' ... yes
Jason,()在Python中不是必需的。
不要暗示这不是你没有想到的,但我发现最简单的事情通常是最好的:
if ("foo" in foo) and ("bar" in foo): # do stuff
>>> ok {'five': '5', 'two': '2', 'one': '1'} >>> if ('two' and 'one' and 'five') in ok: ... print "cool" ... cool
这似乎工作