2011-10-14 31 views
15

说我有一本字典,并且我想检查一个密钥是否映射到非空值。这样做的一个方法是Len函数:检查字典中的值是否定义/长度为零的最Pythonic方法

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 

但是,我不确定哪个更加Pythonic。第一种认为“明确比隐含更好”,但第二种认为“简单比复杂更好”。

我还想知道,如果不使用len调用可能会咬我,因为我正在使用的字典不一定包含字符串,但可能包含其他可用类型(列表,集合等)。 OTOH,前者(带len调用)如果None被存储为值,则代码将被炸毁,而非len版本将按预期工作(将被评估为false)。

哪个版本更安全,更多Pythonic?

编辑:澄清假设:我知道关键是在字典中,我知道值是可以lenable的。我也无法避免将零长度值输入词典。

编辑#2:好像人们错过了我的问题。我并不想以确定检查的最Python化/最安全的方式,如果一个关键出现在一本字典,我想检查是否值长度为零或不

回答

17

如果你知道,关键是在字典中,使用

if mydict["key"]: 
    ... 

它操作简单,易于阅读,并说,“如果捆绑‘密钥’的价值评估为True,有所为有所不为”。要知道最重要的珍闻是,容器类型(字典,列表,元组,STR等)只能评估到True如果他们的len大于0

这也将引发KeyError如果你的前提是一个关键是在违反了mydict

所有这一切使Pythonic。

+0

..并说:“如果与'key'关联的值评估为True,则执行某些操作” - 但我的意图是说“如果值的长度不是零”。分裂我想的头发。 –

+0

@AdamParkin:嗯。那么,如果你有一个长度不为零的物体仍然被评估为False,那么这将是非常不寻常的......并且可能会被破坏。另一方面,如果你想防范没有长度的对象(比如'int's)作为合法值,那么检查'len(value)'就是你所有的东西。但是,除非你有一个很好的理由(例如数据传输/存储等),否则这是一个坏主意。如果你走这条路线,确保你抓住了'TypeError'。 –

13
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的作品,但并不直观。

总之,将它留给测试对象来定义它是否为空并将其转换为布尔值。

+1

对不起,为什么.get比使用[]访问更好? –

+3

@AdamParkin - 因为'[]'可以引发'KeyError','get'不会。 – Nate

+0

这是如何解决我的问题?我正在测试零长度值,而不是测试字典中是否存在密钥。 –

3

here

在布尔操作的上下文中,以及当表达式通过控制流语句中使用的,下面的值被解释为假:FalseNone,所有类型的数字零,并且空字符串和容器(包括字符串,元组,列表,字典,集合和frozensets)。所有其他值都被解释为true。

我认为这是肯定地说,直接评价它是最好的选择 - 虽然,作为@phihag说,它的安全使用get代替,因为它会保护你从KeyError

-1

你的初始条件不符合Python。你为什么要存储一个空值的密钥?你可以删除密钥而不是将其设置为无?

的Python的方式是检查是否存在重点与if key in dictionary,不检查非空值。

+1

我不是检查关键存在,而是检查值的长度。虽然我同意“空”的值不是特别的Pythonic,但它是不可避免的问题领域(它是基于对我的程序的输入,这是我的控制之外的)。我可以在事实之后对字典进行过滤,并删除键值为空的键对,但这需要我询问的代码。 –

+3

关于存储具有空容器值的键或任何其他False值没有任何不合理之处。 –

0

最Python的方式将是没有定义的未定义的值(尽管这是否可用取决于你使用它的东西),并使用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]。如果你确定你想要的密钥在字典中,你应该使用它。使用len(mydict[key]) > 0。这仅适用于定义了__len__的值。通常情况下,集装箱价值的真值取决于__len__,所以上述情况更可取。
+0

我确信关键在于字典,我知道价值观是可以宽容的。虽然我没有在这个解决方案中看到真正的答案,但是您是否按照相反的首选顺序来推荐这3个答案? –

+0

答案取决于你的具体情况。在你的情况下,使用'mydict [key]'。 Pythonic比使用'len'要好得多。 '如果a:'意味着“如果'a'不是空的:”在Python中如果'a'是一个容器。 – Robin

+1

关于存储具有空容器值或其他任何假值的密钥没有任何不合理之处。 –

1

标题和第一句话居然表示两个略有不同的问题。

为标题问题

如果在字典中的值定义

检查的最Python的方式我会用

"key" in mydict 

去为第二问题

说我有一本字典,我想检查一个密钥是否映射到一个非空值。

我会去与

"key" in mydict and bool(mydict["key"]) 

其中的检查,看看是否“钥匙”的第一部分是目前在mydict,第二部分用于再假的“钥匙”以外的值返回true ,无,空字符串,空字典,空列表和0

+0

同样,我正在测试字典中的*值*,而不是密钥。 –

0

你的两个例子我倾向于第二种。

不过,我建议对存储空键。另外一个defaultdict将工作做好的位置:

>>> from collections import defaultdict 
>>> d = defaultdict(list) 
>>> d[1].append(1) 
>>> 1 in d 
True 

如果您必须存储空键,你不需要字符串值"True""False"。只是这样做:

print bool(mydict[key]) 
+0

这是检查的关键1,而不是值1。正如我澄清的假设中提到的,避免零len *值*是不可避免的 –

+0

@亚当:我怀疑它是否真的是不可避免的。这感觉就像是滥用字典来存储空密钥。另外,我的回答的第二部分是建议,而不是处方。 –

+2

为什么你建议不要存储空键?通过这样做,你正在丢弃信息。 “这把钥匙被看见,但没有价值”可能与“从未见过这把钥匙”有潜在的不同。 –

2

我会使用第一个选项的变化:

>>> 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。你永远不会有一个负长度的对象。另外,可以通过print直接打印布尔型号为TrueFalse,因此您不需要条件式。

+0

使用'len'而不是'mydict [“key”]''不* Pythonic。 –

+0

没有意识到bool(container)和bool(len(container))是等价的语句。更新后的文章以反映。 – Nathan

+0

更改了我的投票。 –

相关问题