假设我有一个字典,我想检查一个键是否映射到非空值。执行此操作的一种方法是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 /最安全的方法,我正在尝试检查值是否为零长度
如果您知道密钥在字典中,请使用
if mydict["key"]:
...
它简单,易于阅读,并说,“如果与'关键'相关的价值评估为True
,那就做点什么”。要知道的重要信息是容器类型(dict,list,tuple,str等)仅在True
大于0时才评估为len
。
如果你的密钥在KeyError
的前提被违反,它也会提高mydict
。
所有这一切使它成为Pythonic。
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。
我会使用第一个选项的变体:
>>> 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
。你永远不会有负长度的物体。此外,布尔人True
和False
可以直接通过print
打印,所以你不需要条件。
标题和第一句实际上表达了两个略有不同的问题。
对于标题问题
检查字典中的值是否已定义的最Pythonic方法
我会去的
"key" in mydict
而对于第二个问题
假设我有一个字典,我想检查一个键是否映射到非空值。
我会去的
"key" in mydict and bool(mydict["key"])
第一部分检查mydict中是否存在“key”,第二部分为“key”的所有值返回true,然后是False,None,空字符串,空字典,空列表和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
否则,您有三种选择:
mydict.get
。如果密钥可能在字典中,也可能不在字典中,则应使用此密钥。mydict[key]
。如果你确定你想要的密钥在dict中,你应该使用它。len(mydict[key]) > 0
。这仅在值定义了__len__
时才有效。通常,容器值的真值无论如何都取决于__len__
,因此以上是优选的。在你的两个例子中,我更喜欢第二个。
但是,我建议不要存储空键。此外,defaultdict在这里也可以正常工作:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d[1].append(1)
>>> 1 in d
True
如果必须存储空键,则不需要字符串值"True"
和"False"
。这样做:
print bool(mydict[key])
您可以通过以下方式检查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]))
你的初始条件不是Pythonic。为什么要存储空值的键?您可以删除密钥而不是将其设置为无吗?
Pythonic的方法是用if key in dictionary
检查密钥存在,而不是检查非空值。