Наиболее Pythonic способ проверить, если значение в словаре определено / имеет нулевую длину - PullRequest
23 голосов
/ 14 октября 2011

Скажем, у меня есть словарь, и я хочу проверить, сопоставлен ли ключ непустому значению.Одним из способов сделать это может быть функция len:

mydict = {"key" : "value", "emptykey" : ""}
print "True" if len(mydict["key"]) > 0 else "False"  # prints true
print "True" if len(mydict["emptykey"]) > 0 else "False"  # prints false

Однако можно полагаться на семантику Python и то, как, если объект определен, он оценивается как true и пропускает вызов len:

mydict = {"key" : "value", "emptykey" : ""}
print "True" if mydict["key"] else "False"  # prints true
print "True" if mydict["emptykey"] else "False"  # prints false

Тем не менее, я не уверен, что является более Pythonic.Первый чувствует, что «явный лучше, чем неявный», однако второй чувствует, что «простой - лучше, чем сложный».

Мне также интересно, может ли пропущенный вызов len укусить меня, как дикту, с которым я работаюне обязательно содержит строки, но может содержать другие типы (списки, наборы и т. д.).OTOH, в первом (с вызовом len), если None будет сохранен как значение, код будет взорван, тогда как non-len версия будет работать как положено (будет иметь значение false).

Какая версия являетсябезопаснее и больше Pythonic?

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

Правка № 2: Кажется, что люди упускают смысл моего вопроса.Я не пытаюсь определить самый Pythonic / самый безопасный способ проверки наличия ключа в словаре, я пытаюсь проверить, имеет ли значение нулевой длины или нет

Ответы [ 9 ]

26 голосов
/ 14 октября 2011

Если вы знаете, что ключ находится в словаре, используйте

if mydict["key"]:
    ...

Он прост, легко читается и говорит: «Если значение, связанное с ключом, оценивается как True, сделайте что-нибудь». Важно знать, что типы контейнеров (dict, list, tuple, str и т. Д.) Оцениваются как True, только если их len больше 0.

Это также повысит KeyError, если ваша предпосылка, что ключ в mydict нарушена.

Все это делает его Pythonic.

14 голосов
/ 14 октября 2011
print (bool(mydict.get('key')))

или в операторе if:

print ('True' if mydict.get('key') else 'False')

Если значение, которое вы не указали, является ошибкой (т.е. вы ожидаете, что оно будет там), вам следует выбрать решение № 2, т.е.

print ('True' if mydict['key'] else 'False')

Это позволяет mydict['key'] выбрать наиболее эффективное определение для того, чтобы быть пустым. Для некоторых объектов (например, в кластерах) определение фактической длины является довольно сложной операцией, тогда как просто определить, является ли объект пустым или нет.

Вы также можете сравнить с '', то есть mydict['key'] == '', чтобы сделать ваше выражение совершенно ясным. Использование len работает, но не так интуитивно понятно.

Таким образом, оставьте это тестируемому объекту, чтобы определить, пуст он или нет и просто приведите его к bool.

3 голосов
/ 14 октября 2011

Я бы использовал вариант первого варианта:

>>> mydict = {"key" : "value", "emptykey" : ""}
>>> print bool(mydict["key"])
True
>>> print bool(mydict["emptykey"])
False

Любой класс, предоставляющий __len__, может быть непосредственно преобразован в логическое значение (см. Проверка значения истины ), поэтому bool(container) является эквивалентом bool(len(container)). Длина 0 станет логическим значением False, а все остальные значения будут True. У вас никогда не будет объекта отрицательной длины. Кроме того, логические значения True и False могут быть распечатаны напрямую через print, поэтому вам не нужны условные выражения.

3 голосов
/ 14 октября 2011

С здесь :

В контексте логических операций, а также когда выражения используются в выражениях потока управления, следующие значения интерпретируются как ложные: False, None, числовой ноль всех типов и пустые строки и контейнеры (включая строки, кортежи, списки, словари, наборы и фрозенсеты).Все остальные значения интерпретируются как истина.

Я думаю, можно с уверенностью сказать, что прямая оценка - ваш лучший вариант, хотя, как сказал @phihag, безопаснее использовать get вместо этого, поскольку это защитит вас от KeyError.

1 голос
/ 14 октября 2011

Заголовок и первое предложение на самом деле выражают два несколько разных вопроса.

Для заглавного вопроса

Самый пифоновский способ проверки, определено ли значение в словаре

Я бы пошел с

"key" in mydict

и для второго вопроса

Скажем, у меня есть словарь, и я хочу проверить, если ключотображается в непустое значение.

Я бы пошел с

"key" in mydict and bool(mydict["key"])

Первая часть которого проверяет, присутствует ли «ключ» в mydict, а вторая частьвозвращает true для всех значений «ключа», кроме False, None, пустой строки, пустого словаря, пустого списка и 0.

0 голосов
/ 14 февраля 2019

Вы можете просто проверить, что любое значение в dict имеет нулевую длину или нет:

# To get keys which having zero length value:
keys_list = [key for key,val in mydict.items() if not val]


# To check whether the dict has any zero length value in it (returns True or False):
any_empty_vals = bool(len(['' for x in data_dict.values() if not x]))
0 голосов
/ 14 октября 2011

Из ваших двух примеров я предпочитаю второй.

Однако я не советую хранить пустые ключи.Также здесь будет работать defaultdict:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d[1].append(1)
>>> 1 in d
True

Если вам нужно хранить пустые ключи, вам не нужны строковые значения "True" и "False".Просто сделайте это:

print bool(mydict[key])
0 голосов
/ 14 октября 2011

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

mydict = {"key" : "value"}
print "True" if "key" in mydict else "False"  # prints true
print "True" if "emptykey" in mydict else "False"  # prints false

В противном случае у вас есть три варианта:

  1. Используйте mydict.get. Вы должны использовать это, если ключ может или не может быть в словаре.
  2. Используйте mydict[key]. Вы должны использовать это, если вы уверены, что ключ, который вы хотите, находится в диктовке.
  3. Используйте len(mydict[key]) > 0. Это работает, только если значение имеет __len__. Обычно значение истинности значения контейнера в любом случае зависит от __len__, поэтому приведенные выше предпочтительны.
0 голосов
/ 14 октября 2011

Ваши начальные условия не Pythonic. Почему вы храните ключ с пустым значением? Можете ли вы удалить ключ вместо того, чтобы установить его на None?

Pythonic способ проверить наличие ключа с помощью if key in dictionary, не проверяя непустое значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...