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

时间:2011-10-14 17:28:24

标签: coding-style dictionary python

说我有一本字典,我想检查一个键是否映射到非空值。这样做的一种方法是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 /最安全的方法,我正在尝试检查 值是否为零长度

12 个答案:

答案 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:FalseNone,所有类型的数字零和空字符串和容器(包括字符串,元组,列表,字典,集合和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。你永远不会有负长度的物体。此外,布尔值TrueFalse可以通过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

否则,您有三个选择:

  1. 使用mydict.get。如果密钥可能在字典中,也可能不在字典中,则应使用此字符。
  2. 使用mydict[key]。如果你确定你想要的密钥在dict中,你应该使用它。
  3. 使用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检查密钥存在,而不是检查非空值。