Я хотел проверить, существует ли ключ в словаре, прежде чем обновлять значение для ключа. Я написал следующий код:
if 'key1' in dict.keys():
print "blah"
else:
print "boo"
Я думаю, что это не лучший способ выполнить эту задачу. Есть ли лучший способ проверить ключ в словаре?
in
- это предполагаемый способ проверить наличие ключа в dict
.
d = dict()
for i in range(100):
key = i % 10
if key in d:
d[key] += 1
else:
d[key] = 1
Если вы хотите по умолчанию, вы всегда можете использовать dict.get ()
:
d = dict()
for i in range(100):
key = i % 10
d[key] = d.get(key, 0) + 1
и если вы хотите всегда обеспечивать значение по умолчанию для любого ключа, вы можете использовать defaultdict
из модуля collections
, например так:...
from collections import defaultdict
d = defaultdict(int)
for i in range(100):
d[i % 10] += 1
но в целом ключевое слово in
- лучший способ сделать это...
Вам не нужно звонить ключам:
if 'key1' in dict:
print "blah"
else:
print "boo"
Это будет намного быстрее, поскольку он использует хеширование словаря, а не линейный поиск, который будут делать вызывающие ключи.
Вы можете проверить наличие ключа в словаре, используя < b > in < / b > Ключевое слово:
d = {'a': 1, 'b': 2}
'a' in d # <== evaluates to True
'c' in d # <== evaluates to False
Обычное использование для проверки существования ключа в словаре перед его изменением - инициализация значения по умолчанию (например,. если ваши значения, например, являются списками, и вы хотите убедиться, что есть пустой список, к которому вы можете добавить при вставке первого значения для ключа). В таких случаях вы можете найти < a href = "https://docs.python.org/2/library/collections.html#collections.defaultdict" > collections.defaultdict () < / code > < / a > тип, представляющий интерес.
В старом коде вы также можете найти некоторые варианты использования has_key ()
, устаревшего метода проверки наличия ключей в словарях (вместо этого просто используйте key_name в dict_name
).
Вы можете сократить это:
if 'key1' in dict:
...
Тем не менее, это в лучшем случае косметическое улучшение. Почему вы считаете, что это не лучший способ?
Для получения дополнительной информации о скорости выполнения предложенных методов принятого ответа (10-метровые петли):
mydict.get ('key')
прошло время 1,84 секmydefaultdict ['key']
прошедшее время 1.07 секПоэтому использование in
или defaultdict
рекомендуется против get
.
Я бы порекомендовал использовать метод setdefault
. Похоже, он сделает все, что вы хотите.
>>> d = {'foo':'bar'}
>>> q = d.setdefault('foo','baz') #Do not override the existing key
>>> print q #The value takes what was originally in the dictionary
bar
>>> print d
{'foo': 'bar'}
>>> r = d.setdefault('baz',18) #baz was never in the dictionary
>>> print r #Now r has the value supplied above
18
>>> print d #The dictionary's been updated
{'foo': 'bar', 'baz': 18}
Словарь в python имеет метод get ('key', default). Таким образом, вы можете просто установить значение по умолчанию в случае отсутствия ключа.
values = {...}
myValue = values.get('Key', None)
Как насчет использования EAFP (легче просить прощения, чем разрешения):
try:
blah = dict["mykey"]
# key exists in dict
except KeyError:
# key doesn't exist in dict
Смотрите другие сообщения SO:
https://stackoverflow.com/questions/1835756/using-try-vs-if-in-python или
https://stackoverflow.com/questions/204308/checking-for-member-serence-in-python
Способы получения результатов:
Что лучше, зависит от 3 вещей:
Подробнее: http://paltman.com/try-exclude-performance-in-python-a-simple-test/
Использование try / block вместо «in» или «if»:
try:
my_dict_of_items[key_i_want_to_check]
except KeyError:
# Do the operation you wanted to do for "key not present in dict".
else:
# Do the operation you wanted to do with "key present in dict."
Вы можете использовать метод has_key ():
if dict.has_key('xyz')==1:
#update the value for the key
else:
pass
Просто к вашему сведению добавление к Крису. Б (лучший ответ):
d = defaultdict(int)
Работает также; причина в том, что вызов int ()
возвращает 0
, что и defaultdict
делает за кулисами (при построении словаря), отсюда и название «Факторная функция» в документации.
Проверьте, существует ли данный ключ в словаре
Чтобы понять, как это сделать, мы сначала проверяем, какие методы мы можем вызвать в словаре. Вот методы:
d={'clear':0, 'copy':1, 'fromkeys':2, 'get':3, 'items':4, 'keys':5, 'pop':6, 'popitem':7, 'setdefault':8, 'update':9, 'values':10}
Python Dictionary clear() Removes all Items
Python Dictionary copy() Returns Shallow Copy of a Dictionary
Python Dictionary fromkeys() Creates dictionary from given sequence
Python Dictionary get() Returns Value of The Key
Python Dictionary items() Returns view of dictionary (key, value) pair
Python Dictionary keys() Returns View Object of All Keys
Python Dictionary pop() Removes and returns element having given key
Python Dictionary popitem() Returns & Removes Element From Dictionary
Python Dictionary setdefault() Inserts Key With a Value if Key is not Present
Python Dictionary update() Updates the Dictionary
Python Dictionary values() Returns view of all values in dictionary
Жестоким методом проверки того, существует ли ключ, может быть метод get ()
:
d.get("key")
Два других интересных метода items ()
иkeys ()
звучит как слишком много работы. Итак, давайте рассмотрим, является ли get ()
правильным методом для нас. У нас есть наш дикт d
:
d= {'clear':0, 'copy':1, 'fromkeys':2, 'get':3, 'items':4, 'keys':5, 'pop':6, 'popitem':7, 'setdefault':8, 'update':9, 'values':10}
Печать показывает, что ключ, которого у нас нет, вернет None
:
print(d.get('key')) #None
print(d.get('clear')) #0
print(d.get('copy')) #1
Мы < strike > may < / strike > используйте это, чтобы получить информацию, если ключ присутствует или нет.
Но учтите это, если мы создадим дикт с одним key: No
:
d= {'key':None}
print(d.get('key')) #None
print(d.get('key2')) #None
Руководство тем, что метод get ()
не является надежным в случае, если некоторые значения могут быть None
.
Эта история должна иметь более счастливый конец. Если мы используем компаратор in
:
print('key' in d) #True
print('key2' in d) #False
Мы получаем правильные результаты. Мы можем изучить код байта Python:
import dis
dis.dis("'key' in d")
# 1 0 LOAD_CONST 0 ('key')
# 2 LOAD_NAME 0 (d)
# 4 COMPARE_OP 6 (in)
# 6 RETURN_VALUE
dis.dis("d.get('key2')")
# 1 0 LOAD_NAME 0 (d)
# 2 LOAD_METHOD 1 (get)
# 4 LOAD_CONST 0 ('key2')
# 6 CALL_METHOD 1
# 8 RETURN_VALUE
Это показывает, что оператор in
compare не просто более надежен, но даже быстрее, чем get ()
.
В словаре Python есть метод, называемый __contains__
. Этот метод вернет True, если в словаре есть ключ, а другой возвращает False.
>>> temp = {}
>>> help(temp.__contains__)
Help on built-in function __contains__:
__contains__(key, /) method of builtins.dict instance
True if D has a key k, else False.
Совместное использование еще одного способа проверки наличия ключа с использованием логических операторов.
d = {'a': 1, 'b':2}
keys = 'abcd'
for k in keys:
x = (k in d and 'blah') or 'boo'
print(x)
Это возвращается
>>> blah
>>> blah
>>> boo
>>> boo
Объяснение
Сначала вы должны знать, что в Python 0
, None
или объекты с нулевой длиной оцениваются как False
. Все остальное оценивается как «Истина». Булевы операции оцениваются слева направо и возвращают операнд, а не True или False.
Давайте посмотрим пример:
>>> 'Some string' or 1/0
'Some string'
>>>
Поскольку 'Some string '
оценивается как True
, остальная часть or
не оценивается, и нет деления на нулевую ошибку.
Но если мы переключаемся, порядок 1 / 0
оценивается первым и вызывает исключение:
>>> 1/0 or 'Some string'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>>
Мы можем использовать это для шаблона для проверки наличия ключа.
(k in d and 'blah')
делает то же самое, что
if k in d:
'blah'
else:
False
Это уже возвращает правильный результат, если ключ существует, но мы хотим, чтобы он печатал «бу», когда это не так. Итак, мы берем результат и или
его с ' boo '
>>> False or 'boo'
'boo'
>>> 'blah' or 'boo'
'blah'
>>>
Вы можете использовать цикл for
для итерации по словарю и получить имя ключа, который вы хотите найти в словаре, после этого проверьте, существует ли он или нет, используя условие if
:
dic = {'first' : 12, 'second' : 123}
for each in dic:
if each == 'second':
print('the key exists and the corresponding value can be updated in the dictionary')