说我有一本字典,我想检查一个键是否映射到非空值。这样做的一种方法是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 /最安全的方法,我正在尝试检查 值是否为零长度
答案 0 :(得分:25)
如果您知道密钥在字典中,请使用
if mydict["key"]:
...
它简单易读,并且说,“如果与'key'相关联的值评估为True
,则执行某些操作”。要知道的重要信息是,如果容器类型(dict,list,tuple,str等)的True
大于0,则它们仅评估为len
。
如果违反了KeyError
中某个密钥的前提,它也会引发mydict
。
这一切都让它成为Pythonic。
答案 1 :(得分:14)
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。
答案 2 :(得分:3)
来自here:
在布尔运算的上下文中,以及控制流语句使用表达式时,以下值被解释为false:
False
,None
,所有类型的数字零和空字符串和容器(包括字符串,元组,列表,字典,集合和frozensets)。所有其他值都被解释为true。
我认为直接评估它是你最好的选择是安全的 - 尽管正如@phihag所说,使用get
会更安全,因为它可以保护你免受KeyError
的攻击。 / p>
答案 3 :(得分: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
。你永远不会有负长度的物体。此外,布尔值True
和False
可以通过print
直接打印,因此您不需要条件。
答案 4 :(得分:1)
标题和第一句实际上表达了两个略有不同的问题。
标题问题
检查字典中的值是否已定义的最Pythonic方法
我会去
"key" in mydict
和第二个问题
说我有一本字典,我想检查一个键是否映射到非空值。
我会去
"key" in mydict and bool(mydict["key"])
第一部分检查mydict中是否存在“key”,第二部分为“key”的所有值返回true,然后是False,None,空字符串,空字典,空列表和0
答案 5 :(得分: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__
,因此上述情况更可取。答案 6 :(得分:0)
在你的两个例子中,我更喜欢第二个。
但是,我建议不要存储空键。此外,defaultdict在这里也可以正常工作:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d[1].append(1)
>>> 1 in d
True
如果您必须存储空键,则不需要字符串值"True"
和"False"
。就这样做:
print bool(mydict[key])
答案 7 :(得分: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]))
答案 8 :(得分:0)
在解析函数的kwargs
时,为什么字典可能包含一个值为None的键确实有意义,并且您需要知道该函数的参数是传递为None还是仅仅传递没有定义的。这是消除歧义的最简单方法:
def myfunct(**kwargs):
if 'thiskey' not in kwargs:
# this means that 'thiskey' was never passed into myfunct().
kwargs['thiskey'] = <default value>
else:
# you can define the defaults differently;
# if was defined as None, keep it set to None this way.
kwargs['thiskey'] = kwargs.get('thiskey', None)
# otherwise, any defined value passes through.
# do stuff...
答案 9 :(得分:0)
自从我来到这里开始,我们是否可以检查是否存在字典键,答案是:
if mydict.get(key,0):
---
并且对于键的长度> 0,@ Ethan Furman已经提供了答案
if mydict[key]:
---
答案 10 :(得分:0)
mydict = {"key" : "value", "emptykey" : ""}
if not mydict["emptykey"]:
print("empty value")
else:
print("value of emptykey",mydict["emptykey"])
输出
empty value
答案 11 :(得分:-1)
你的初始条件不是Pythonic。为什么要存储空值的键?您可以删除密钥而不是将其设置为无吗?
Pythonic方法是使用if key in dictionary
检查密钥存在,而不是检查非空值。