Как я проверяю, что несколько ключей находятся в dict в единственной передаче?

Это также используется для встроенного программирования, где устройства IO часто отображаются на определенных адресах памяти

190
задан Jean-François Corbett 11 October 2018 в 22:59
поделиться

10 ответов

Ну, вы могли бы сделать это:

>>> if all (k in foo for k in ("foo","bar")):
...     print "They're there!"
...
They're there!
318
ответ дан 23 November 2019 в 05:35
поделиться
>>> if 'foo' in foo and 'bar' in foo:
...     print 'yes'
... 
yes

Джейсон, () не нужны в Python.

1
ответ дан 23 November 2019 в 05:35
поделиться

Решение Алекса Мартелли set (query) <= set (my_dict) является самым коротким кодом, но, возможно, не самым быстрым. Предположим, Q = len (запросы) и D = len (my_dict).

Для создания двух наборов требуется O (Q) + O (D), а затем (можно надеяться!) Только O (min (Q, D )) для выполнения теста подмножества - конечно, при условии, что поиск набора Python равен O (1) - это наихудший случай (когда ответ - Истина).

Генераторное решение hughdbrown (и др.?) all (k в my_dict для k в запросах) - это наихудший вариант O (Q).

Усложняющие факторы:
(1) все циклы в гаджете на основе набора выполняются на скорости C, тогда как гаджет на основе любого цикла выполняет цикл по байт-коду.
(2) Вызывающий гаджет на основе любого может иметь возможность использовать любые сведения о вероятности сбоя для соответствующего упорядочивания элементов запроса, тогда как гаджет на основе наборов не допускает такого контроля.

Как всегда, если скорость важна, сравнительный анализ в рабочих условиях - хорошая идея.

4
ответ дан 23 November 2019 в 05:35
поделиться

Не хочу сказать, что это не то, о чем вы не думали, но я считаю, что самое простое обычно лучше:

if ("foo" in foo) and ("bar" in foo):
    # do stuff
1
ответ дан 23 November 2019 в 05:35
поделиться

Если вы хотите:

  • также получить значения для ключей
  • проверьте более одного словаря

, затем:

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
1
ответ дан 23 November 2019 в 05:35
поделиться

Как насчет использования лямбда?

 if reduce( (lambda x, y: x and foo.has_key(y) ), [ True, "foo", "bar"] ): # do stuff
1
ответ дан 23 November 2019 в 05:35
поделиться

Как насчет этого:

if all(key in foo for key in ["foo","bar"]):
    # do stuff
    pass
9
ответ дан 23 November 2019 в 05:35
поделиться
if set(("foo", "bar")) <= set(myDict): ...
112
ответ дан 23 November 2019 в 05:35
поделиться

Использование устанавливает :

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

Альтернативно:

if set(("foo", "bar")) <= set(foo):
    #do stuff
22
ответ дан 23 November 2019 в 05: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
36
ответ дан 23 November 2019 в 05:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: