Есть ли умный питонический способ проверить, есть ли элемент (ключ, значение) в dict?Как проверить, присутствует ли пара слов-значение в словаре?
a={'a':1,'b':2,'c':3}
b={'a':1}
c={'a':2}
b in a:
--> True
c in a:
--> False
Есть ли умный питонический способ проверить, есть ли элемент (ключ, значение) в dict?Как проверить, присутствует ли пара слов-значение в словаре?
a={'a':1,'b':2,'c':3}
b={'a':1}
c={'a':2}
b in a:
--> True
c in a:
--> False
Использовать свойство короткого замыкания and
. Таким образом, если левая рука ложна, тогда вы не получите KeyError
, проверяя значение.
>>> a={'a':1,'b':2,'c':3}
>>> key,value = 'c',3 # Key and value present
>>> key in a and value == a[key]
True
>>> key,value = 'b',3 # value absent
>>> key in a and value == a[key]
False
>>> key,value = 'z',3 # Key absent
>>> key in a and value == a[key]
False
Это выполняет два словарных поиска, когда один из них достаточно. – GingerPlusPlus
@GingerPlusPlus Это лучше в худшем случае, если не в лучшем случае. –
Можете ли вы уточнить? Почему это лучше, чем '.get()'? – GingerPlusPlus
Вы можете проверить кортеж ключа, значение по отношению к словарю .items()
.
test = {'a': 1, 'b': 2}
print(('a', 1) in test.items())
>>> True
Это очень медленно, поскольку он создает список элементов и выполняет линейный поиск через список. – user2357112
@ user2357112 Правда. Если это критически важная часть программы, я бы пошел с ответом Бхаргава Рао, но я бы сказал, что это более читаемо. –
Будет ли 'iteritems()' быстрее? Я имею в виду, все еще линейный поиск, но память мудрая, это генератор. –
Вы помечено это 2.7, в отличие от 2.x, так что вы можете проверить, является ли кортеж в ДИКТ-х viewitems
:
(key, value) in d.viewitems()
Под капотом, это в основном делает key in d and d[key] == value
.
В Python 3, viewitems
всего items
, но не используйте items
в Python 2! Это построит список и выполнит линейный поиск, используя O (n) время и пространство, чтобы сделать то, что должно быть быстрой проверкой O (1).
Не 'iteritems' в Python2.x считается' items' в Python3? Документы говорят, что 'viewitems' является объектом динамического представления. –
@ cricket_007: Нет, 'iteritems' в Python 2 не имеет эквивалента Python 3. Python 3 'items' - это объект динамического представления, такой как« viewitems »Python 2.7. – user2357112
>>> a = {'a': 1, 'b': 2, 'c': 3}
>>> b = {'a': 1}
>>> c = {'a': 2}
Во-первых вот способ, который работает для python2 и Python3
>>> all(k in a and a[k] == b[k] for k in b)
True
>>> all(k in a and a[k] == c[k] for k in c)
False
В Python3 вы также можете использовать
>>> b.items() <= a.items()
True
>>> c.items() <= a.items()
False
Для python2, эквивалент является
>>> b.viewitems() <= a.viewitems()
True
>>> c.viewitems() <= a.viewitems()
False
Проверка 'if k in a' означает, что проверка' all' будет сообщать '{'d': 4}' как подпункт 'a'. – user2357112
@ пользователь2357112, спасибо. починил это –
Использование get
:
# this doesn't work if `None` is a possible value
# but you can use a different sentinal value in that case
a.get('a') == 1
Использование Try/за исключением:
# more verbose than using `get`, but more foolproof also
a = {'a':1,'b':2,'c':3}
try:
has_item = a['a'] == 1
except KeyError:
has_item = False
print(has_item)
Другие ответы, предполагающие items
в Python3 и viewitems
в Python 2.7 легче читать и более идиоматических, но предложения в этом ответе будет работать в обеих версиях Python без кода совместимости и будет работать в постоянное время. Выбрать свой яд.
a.get('a') == 1
=> True
a.get('a') == 2
=> False
если None
действует пункт:
{'x': None}.get('x', object()) is None
Преобразование мой комментарий в ответ:
Используйте dict.get
метод, который уже представлен в качестве встроенного метода (и я полагаю, является наиболее pythonic)
>>> dict = {'Name': 'Anakin', 'Age': 27}
>>> dict.get('Age')
27
>>> dict.get('Gender', 'None')
'None'
>>>
Согласно документам -
get (key, default) - Возвращает значение для ключа, если ключ находится в словаре, иначе по умолчанию. Если значение по умолчанию не задано, по умолчанию оно равно None, так что этот метод никогда не вызывает KeyError.
Использование .get
, как правило, лучший способ проверить, существует ли пара ключей.
if my_dict.get('some_key'):
# Do something
Существует один нюанс, если ключ существует, но falsy то провалит тест, который не может быть то, что вы хотите. Имейте в виду, что это редко бывает. Теперь обратная проблема является более частым. Это использует in
для проверки наличия ключа. Я часто обнаружил эту проблему при чтении файлов csv.
Пример
# csv looks something like this:
a,b
1,1
1,
# now the code
import csv
with open('path/to/file', 'r') as fh:
reader = csv.DictReader(fh) # reader is basically a list of dicts
for row_d in reader:
if 'b' in row_d:
# On the second iteration of this loop, b maps to the empty string but
# passes this condition statement, most of the time you won't want
# this. Using .get would be better for most things here.
почему бы не использовать '.get()'? – letsc
@letsc: отправьте его как ответ – GingerPlusPlus
Возможный дубликат [Проверить, существует ли данный ключ в словаре] (http://stackoverflow.com/questions/1602934/check-if-a-given-key-already- Существует-в-словаре) – Aaron