Самый Pythonic способ проверки, если значение в словаре определено/имеет нулевую длину
Скажем, у меня есть словарь, и я хочу проверить, не привязан ли ключ к непустому значению. Одним из способов сделать это будет функция 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 укусить меня, поскольку я использую dict, который не обязательно содержит строки, но может содержать другие доступные типы (списки, наборы и т.д.). OTOH, в первом (с вызовом len), если None будет сохранен как значение, код будет взорван, тогда как версия non-len будет работать как ожидалось (будет eval до false).
Какая версия более безопасна и более Pythonic?
Изменить: уточнить предположения: я знаю, что ключ находится в словаре, и я знаю, что значения будут доступными. Я также не могу избежать ввода значений нулевой длины в словарь.
Редактировать # 2: Кажется, что людям не хватает точки моего вопроса. Я не пытаюсь определить самый Pythonic/самый безопасный способ проверки наличия ключа в словаре, я пытаюсь проверить, имеет ли значение нулевой длины или нет
Ответы
Ответ 1
Если вы знаете, что ключ находится в словаре, используйте
if mydict["key"]:
...
Это просто, легко читается и говорит: "Если значение, связанное с" ключом ", оценивается как True
, сделайте что-нибудь". Важно знать, что типы контейнеров (dict, list, tuple, str и т.д.) Оцениваются только True
, если их len
больше 0.
Он также поднимет KeyError
, если ваша предпосылка о том, что ключ находится в mydict
, нарушен.
Все это делает его Pythonic.
Ответ 2
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
Из здесь:
В контексте булевых операций, а также когда выражения используются операторами управления потоком, следующие значения интерпретируются как ложные: False
, None
, числовой нуль всех типов и пустые строки и контейнеры (включая строки, кортежи, списки, словари, наборы и фризоздаты). Все остальные значения интерпретируются как истинные.
Думаю, можно с уверенностью сказать, что прямое оценивание - это ваш лучший вариант - хотя, как сказал @phihag, безопаснее использовать get
вместо этого, так как он защитит вас от KeyError
.
Ответ 4
Я бы использовал вариант первого варианта:
>>> mydict = {"key" : "value", "emptykey" : ""}
>>> print bool(mydict["key"])
True
>>> print bool(mydict["emptykey"])
False
Любой класс, который предоставляет __len__
, может быть преобразован в логическое значение напрямую (см. Проверка достоверности истинности), поэтому bool(container)
является эквивалентом of bool(len(container))
. Длина 0 станет булевым False
, а все остальные длины будут True
. У вас никогда не будет объекта с отрицательной длиной. Кроме того, логические значения True
и False
могут быть напечатаны непосредственно через print
, поэтому вам не требуется условное выражение.
Ответ 5
Название и первое предложение фактически выражают два немного разных вопроса.
Для титульного вопроса
Самый Pythonic способ проверить, определено ли значение в словаре
Я бы пошел с
"key" in mydict
и для второго вопроса
Скажем, у меня есть словарь, и я хочу проверить, не привязан ли ключ к непустому значению.
Я бы пошел с
"key" in mydict and bool(mydict["key"])
Первая часть которой проверяет, присутствует ли "ключ" в mydict, а вторая часть возвращает true для всех значений "ключ", а затем False, None, пустая строка, пустой словарь, пустой список и 0.
Ответ 6
Самый Pythonic-способ состоит в том, чтобы не определять значение undefined (хотя он зависит от того, для чего вы его используете) и используйте in
:
mydict = {"key" : "value"}
print "True" if "key" in mydict else "False" # prints true
print "True" if "emptykey" in mydict else "False" # prints false
В противном случае у вас есть три варианта:
- Используйте
mydict.get
. Вы должны использовать это, если ключ может быть или не быть в словаре.
- Используйте
mydict[key]
. Вы должны использовать это, если вы уверены, что ключ, который вы хотите, находится в dict.
- Используйте
len(mydict[key]) > 0
. Это работает, только если значение имеет __len__
. Обычно значение истины значения контейнера в любом случае зависит от __len__
, поэтому предпочтительные выше.
Ответ 7
Из ваших двух примеров я предпочитаю второй.
Однако я не рекомендую хранить пустые ключи. Также здесь был бы полезен defaultdict:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d[1].append(1)
>>> 1 in d
True
Если вы должны хранить пустые ключи, вам не нужны строковые значения "True"
и "False"
. Просто сделайте следующее:
print bool(mydict[key])
Ответ 8
Ваши начальные условия не являются Pythonic. Почему вы храните ключ с пустым значением? Вы можете удалить ключ, а не устанавливать его на None?
Путь Pythonic - проверить существование ключа с помощью if key in dictionary
, не проверяя непустое значение.