Я хочу сделать что-то вроде:
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
if ("foo","bar") in foo:
#do stuff
Как проверить, находятся ли "foo" и "bar" в dict foo?
Я хочу сделать что-то вроде:
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
if ("foo","bar") in foo:
#do stuff
Как проверить, находятся ли "foo" и "bar" в dict foo?
Хорошо, вы могли бы сделать это:
>>> if all (k in foo for k in ("foo","bar")):
... print "They're there!"
...
They're there!
if set(("foo", "bar")) <= set(myDict): ...
Поместите свои собственные значения для 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
Вам не нужно обертывать левую сторону в наборе. Вы можете просто сделать это:
if {'foo', 'bar'} <= set(some_dict):
pass
Это также работает лучше, чем решение all(k in d...)
.
Использование устанавливает:
if set(("foo", "bar")).issubset(foo):
#do stuff
В качестве альтернативы:
if set(("foo", "bar")) <= set(foo):
#do stuff
Как насчет этого:
if all(key in foo for key in ["foo","bar"]):
# do stuff
pass
Хотя мне нравится Алекс Мартелли, мне кажется, что это не Pythonic. То есть, я думал, что важная часть быть Pythonic должна быть легко понятна. С этой целью <=
нелегко понять.
В то время как больше символов, использование issubset()
, как предлагает ответ Карла Фойгтланда, более понятно. Поскольку этот метод может использовать словарь в качестве аргумента, короткое, понятное решение:
foo = {'foo': 1, 'zip': 2, 'zam': 3, 'bar': 4}
if set(('foo', 'bar')).issubset(foo):
#do stuff
Я хотел бы использовать {'foo', 'bar'}
вместо set(('foo', 'bar'))
, потому что он короче. Тем не менее, это не так понятно, и я думаю, что скобки слишком легко запутаны как словарь.
Решение Alex Martelli set(queries) <= set(my_dict)
является самым коротким кодом, но может быть не самым быстрым. Предположим, что Q = len (запросы) и D = len (my_dict).
Это делает O (Q) + O (D), чтобы сделать два набора, а затем (надеется!) только O (min (Q, D)) выполнить тест подмножества - считая, конечно, что набор Python look-up - O (1) - это худший случай (когда ответ True).
Решение генератора hughdbrown (et al.) all(k in my_dict for k in queries)
является наихудшим случаем O (Q).
Усложняющие факторы:
(1) петли в гаджете на основе набора выполняются со скоростью C, тогда как гаджет-на-основе циклируется по байт-коду.
(2) Абонент гаджета на любой основе может использовать любое знание вероятности неспособности упорядочить элементы запроса соответственно, в то время как гаджет на основе набора не допускает такого контроля.
Как всегда, если скорость важна, бенчмаркинг в рабочих условиях является хорошей идеей.
Я думаю, что это самое умное и питоническое.
{'key1','key2'} <= my_dict.keys()
Как насчет использования лямбда?
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):
# do stuff
>>> if 'foo' in foo and 'bar' in foo:
... print 'yes'
...
yes
Jason,() не нужны в Python.
Вы также можете использовать .issubset()
>>> {0, 1}.issubset({0, 1, 2})
True
>>> {1}.issubset({0, 1, 2})
True
>>> {1}.issubset({'A', 'B', 'C'})
False
>>> {1}.issubset(())
False
>>> ok
{'five': '5', 'two': '2', 'one': '1'}
>>> if ('two' and 'one' and 'five') in ok:
... print "cool"
...
cool
Это похоже на работу