检查字典中值是否定义或长度为零的最 Pythonic 方法

49 投票
13 回答
123677 浏览
提问于 2025-04-17 04:20

假设我有一个字典,我想检查一个键是否对应着一个非空的值。一个方法是使用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的特性:如果一个对象被定义了,它会被视为真值,这样就可以省略len的调用:

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

但是,我不确定哪种方式更符合Python的风格。第一种方式感觉“明确优于隐含”,而第二种方式则感觉“简单优于复杂”。

我还在想,省略len调用会不会给我带来麻烦,因为我正在处理的字典不一定只包含字符串,它可能还包含其他可以用len计算长度的类型(比如列表、集合等)。另一方面,在第一种方式中(使用len调用),如果存储了None作为值,代码会出错,而不使用len的版本则会按预期工作(会被评估为假)。

哪种方式更安全、更符合Python的风格呢?

编辑:澄清一下假设:我知道这个键在字典中,并且我知道值是可以用len计算长度的。我也无法避免字典中出现零长度的值。

编辑#2:似乎大家没有理解我问题的重点。我并不是在寻找检查字典中键是否存在的最Pythonic或最安全的方法,而是想检查一个值是否为零长度

13 个回答

4

我会选择第一种方案的一个变体:

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

任何提供了 __len__ 方法的类,都可以直接转换成布尔值(也就是真或假),具体可以参考 真值测试。所以,bool(container)bool(len(container)) 是等价的。如果长度是0,它会变成布尔值 False,而其他任何长度都会变成 True。你不会遇到负长度的对象。此外,布尔值 TrueFalse 可以直接用 print 打印出来,所以你不需要额外的条件判断。

24
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也是可以的,但不够直观。

总之,让被测试的对象自己来定义是否为空,然后直接转换成布尔值(真或假)。

53

如果你确定字典里有这个键,可以使用

if mydict["key"]:
    ...

这个写法简单易懂,意思是“如果和这个'key'相关的值是True,就做某件事”。这里有个重要的知识点:像字典、列表、元组、字符串这些容器类型,只有在它们的长度大于0的时候,才会被认为是True

另外,如果你假设的键不在mydict里,它会抛出一个KeyError错误。

这些特性让它显得很符合Python的风格。

撰写回答