我想知道能否通过这段代码获得相同的输出结果:
d = {'a':None,'b':'12345','c':None}
nones=False
for k,v in d.items():
if d[k] is None:
nones=True
或者any([v==None for v in d.values()])
但是没有for循环迭代器或生成器?
我想知道能否通过这段代码获得相同的输出结果:
d = {'a':None,'b':'12345','c':None}
nones=False
for k,v in d.items():
if d[k] is None:
nones=True
或者any([v==None for v in d.values()])
但是没有for循环迭代器或生成器?
您可以使用
nones = not all(d.values())
如果所有的值都不是None,那么None将被设置为False,否则为True。虽然这只是一个抽象概念,但在内部它必须遍历值列表。
您可以使用字典视图让Python在C代码中进行循环;这将针对所有值执行成员资格测试,而无需创建新列表:
if None not in d.values():
(在Python 2中,使用dict.viewvalues()
来获取字典视图,因为dict.values()
会返回一个列表)。
Python 3演示:
>>> d = {'a': None, 'c': None, 'b': '12345'}
>>> None not in d.values()
False
这将循环遍历值直到找到匹配项,就像列表成员或适当的any()
测试一样,使得这个测试是O(N)的。这与字典或集合成员测试不同,哈希可以用来给你一个平均固定成本测试。
您没有正确使用any()
函数; 删除[...]
括号:
if any(v is not None for v in d.values()): # Python 2: use d.itervalues() or d.viewvalues()
如果你的目标是测试多个值,而且你需要避免为每个测试进行不断循环,考虑创建一个反向索引:
inverse_index = {}
for key, value in d.items():
inverse.setdefault(value, set()).add(key)
这需要这些值可哈希。现在你可以简单地测试每个值:
if None not in inverse_index:
在O(1)时间内。
any(map(lambda x: x is not None, d.values()))
如何?它更高效,并且在Python 2中也适用。 - Niklas Rx是None
。lambda
调用也有开销,我不确定它是否比其它更高效值得这样做。 - Martijn Pieters
any(d.values())
。但是它会在内部进行循环。无法避免这种情况。 - juanchopanzaany()
的版本包含了一个列表推导式,而不是生成器表达式。any()
会短路,所以一旦找到 True 的结果就会停止。这在生成器表达式上很有效,但当你在列表推导式上使用它时,在any
测试开始之前会创建完整的列表。 - PM 2Ring