检查字典中的值是否已定义/长度为零的最Pythonic方式

问题描述 投票:21回答:9

假设我有一个字典,我想检查一个键是否映射到非空值。执行此操作的一种方法是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。第一种感觉“显性比隐性更好”,然而第二种感觉“简单比复杂更好”。

我也想知道,如果我正在使用的dict不一定包含字符串,但是可以包含其他可以使用的类型(列表,集合等),那么抛弃len调用是否会让我感到困惑。 OTOH,在前者(使用len调用)如果None被存储为值,代码将被炸毁,而非len版本将按预期工作(将eval为false)。

哪个版本更安全,更Pythonic?

编辑:澄清假设:我知道密钥在字典中,我知道值是可以使用的。我也无法避免让零长度值进入字典。

编辑#2:似乎人们忽略了我的问题。我不是要确定检查字典中是否存在密钥的最Pythonic /最安全的方法,我正在尝试检查值是否为零长度

coding-style dictionary python
9个回答
26
投票

如果您知道密钥在字典中,请使用

if mydict["key"]:
    ...

它简单,易于阅读,并说,“如果与'关键'相关的价值评估为True,那就做点什么”。要知道的重要信息是容器类型(dict,list,tuple,str等)仅在True大于0时才评估为len

如果你的密钥在KeyError的前提被违反,它也会提高mydict

所有这一切使它成为Pythonic。


15
投票
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
投票

来自here

在布尔运算的上下文中,以及控制流语句使用表达式时,以下值被解释为false:FalseNone,所有类型的数字零,以及空字符串和容器(包括字符串,元组,列表,字典) ,集和frozensets)。所有其他值都被解释为true。

我认为直接评估它是你最好的选择是安全的 - 尽管如@phihag所说,使用get更安全,因为它可以保护你免受KeyError的伤害。


3
投票

我会使用第一个选项的变体:

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

任何提供__len__的类都可以直接转换为布尔值(参见Truth Value Testing),因此bool(container)相当于bool(len(container))。长度为0将成为布尔值False,而所有其他长度将为True。你永远不会有负长度的物体。此外,布尔人TrueFalse可以直接通过print打印,所以你不需要条件。


1
投票

标题和第一句实际上表达了两个略有不同的问题。

对于标题问题

检查字典中的值是否已定义的最Pythonic方法

我会去的

"key" in mydict

而对于第二个问题

假设我有一个字典,我想检查一个键是否映射到非空值。

我会去的

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

第一部分检查mydict中是否存在“key”,第二部分为“key”的所有值返回true,然后是False,None,空字符串,空字典,空列表和0。


0
投票

最Pythonic的方法是不定义未定义的值(尽管这是否可用取决于你使用它的是什么)并使用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]。如果你确定你想要的密钥在dict中,你应该使用它。
  3. 使用len(mydict[key]) > 0。这仅在值定义了__len__时才有效。通常,容器值的真值无论如何都取决于__len__,因此以上是优选的。

0
投票

在你的两个例子中,我更喜欢第二个。

但是,我建议不要存储空键。此外,defaultdict在这里也可以正常工作:

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

如果必须存储空键,则不需要字符串值"True""False"。这样做:

print bool(mydict[key])

0
投票

您可以通过以下方式检查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]))

-1
投票

你的初始条件不是Pythonic。为什么要存储空值的键?您可以删除密钥而不是将其设置为无吗?

Pythonic的方法是用if key in dictionary检查密钥存在,而不是检查非空值。

© www.soinside.com 2019 - 2024. All rights reserved.