Проверьте, содержит ли список какие-либо ключи dict

#python #list #dictionary

Вопрос:

 d = {('shot',): ['V'], ('I',): ['NP']}
s = ["I", "shot"]
s1 = ["I"]
s2 = ["shot"]

print(str(tuple(s,)))
print([i in d for i in tuple(s,)])
print(bool(set(tuple(s,)).intersection(d)))
print(d[tuple(s1,)])
print(d[tuple(s2,)])
for i in set(tuple(s,)).intersection(d):
    print("Element " i " was found.")
 

Предположим, у меня есть диктант, подобный вышеупомянутому, где каждый ключ является кортежем. Почему это является результатом:

 ('I', 'shot')
[False, False]
False
['NP']
['V']
 

Вместо этого:

 ('I', 'shot')
[True, True]
True
['NP']
['V']
 

Комментарии:

1. Не могли бы вы быть более конкретными?

2. Почему tuple(s,) и не просто s так ?

Ответ №1:

Ни I то , ни shot другое не являются ключами d , так что оба будут False . Когда вы создаете кортеж из списка, каждое значение в списке используется для создания кортежа:

 >>> tuple(["I", "shot"], )
('I', 'shot')
 

Поэтому, когда вы повторяете этот список в своем понимании списка:

 [i in d for i in tuple(s,)]
 

То, что вы эффективно делаете, это:

 for i in ('I', 'shot'):
  if i in d:  # this will be 'I' in the first iteration, 'shot' in the next
      ...
 

Поскольку ни один из I них или shot сами по себе не являются ключами, результат таков False . Ключи, фактически используемые в вашем словаре, являются кортежами, а не строками (именно это вы в конечном итоге ищете).

Однако вместо этого вы могли бы захотеть (поскольку tuple(s, ) преобразование не приносит ничего полезного) найти кортеж со строкой в качестве первого элемента в словаре, а не повторять его:

 >>> [(i, ) in d for i in s]
[True, True]
 

Подводя итог:

 >>> 'I' in d
False
>>> 'shot' in d
False
>>> ('shot', ) in d
True
>>> ('I', ) in d
True
 

В последних двух примерах создается кортеж, а затем проверяется, является ли этот кортеж ключом в словаре.

Та же путаница с ключами и их значениями также может быть причиной вашей проблемы set , но вы хотели бы быть более откровенными — используйте d.keys() , если вам нужен итератор, который дает вам ключи только в словаре, а затем пересекает два набора, которые вы считаете необходимыми для достижения желаемого.