检查字典中值是否定义或长度为零的最 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的特性:如果一个对象被定义了,它会被视为真值,这样就可以省略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 个回答
我会选择第一种方案的一个变体:
>>> 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
打印出来,所以你不需要额外的条件判断。
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
也是可以的,但不够直观。
总之,让被测试的对象自己来定义是否为空,然后直接转换成布尔值(真或假)。
如果你确定字典里有这个键,可以使用
if mydict["key"]:
...
这个写法简单易懂,意思是“如果和这个'key'相关的值是True
,就做某件事”。这里有个重要的知识点:像字典、列表、元组、字符串这些容器类型,只有在它们的长度大于0的时候,才会被认为是True
。
另外,如果你假设的键不在mydict
里,它会抛出一个KeyError
错误。
这些特性让它显得很符合Python的风格。