python-检查dict的任何值是否不是None(没有迭代器)

python-检查dict的任何值是否不是None(没有迭代器),python,dictionary,nonetype,Python,Dictionary,Nonetype,我想知道是否有可能获得与此代码相同的输出: d = {'a':None,'b':'12345','c':None} nones=False for k,v in d.items(): if d[k] is None: nones=True 或 但是没有for循环迭代器或生成器?您可以让Python使用;这将针对所有值执行成员资格测试,而不创建新列表: if None not in d.viewvalues(): 在Python 3中,dict.values()也返回

我想知道是否有可能获得与此代码相同的输出:

d = {'a':None,'b':'12345','c':None}
nones=False
for k,v in d.items(): 
  if d[k] is None:
    nones=True      


但是没有for循环迭代器或生成器?

您可以让Python使用;这将针对所有值执行成员资格测试,而不创建新列表:

if None not in d.viewvalues():
在Python 3中,
dict.values()
也返回字典视图

Python 2上的演示:

>>> d = {'a': None, 'c': None, 'b': '12345'}
>>> None not in d.viewvalues()
False
这将在值上循环,直到找到匹配项,就像列表成员资格或适当的
any()
test一样,使其成为O(N)测试。这与字典或集合成员资格测试不同,在字典或集合成员资格测试中,可以使用哈希平均为您提供固定成本测试

您没有正确使用
any()
;放下
[…]
括号:

if any(v is not None for v in d.itervalues()):  # Python 3: use d.values()

如果您的目标是测试某些值,并且需要避免每次测试的常数循环,那么请考虑创建一个反向索引:

inverse_index = {}
for key, value in d.items():
    inverse.setdefault(value, set()).add(key)
但是,这要求这些值是可散列的。现在,您可以简单地测试每个值:

if None not in inverse_index:
在O(1)时间内。

您可以使用

nones = not all(d.values())

如果所有值都不是None,则nones将设置为False,否则为True。不过这只是一个抽象,在内部它必须在值列表上迭代。

如果不在列表上迭代,就无法检查列表中的值。。您需要检查所有的值;循环到底有什么问题?你不需要理解列表。只要
任何(d.values())
。但这是内部循环。这是无法避免的。罗伯特,看看哈希表是如何工作的。你可能会在那里找到你想要的东西。为什么这个问题被否决得如此糟糕?那
any(map(lambda x:x不是None,d.values())
在Python3中更有效,在Python2中也有效呢?@NiklasR:
x肯定是None
lambda
调用也有成本,我不确定这是否更有效,是否值得。@NiklasR它比使用python3变体(使用
values()
)更糟糕,后者将在Python 2中创建一个丑陋的列表,但在生成器表达式中使用它,而不是在最终循环中使用两次,创建一个额外的列表,从而浪费更多。@NiklasR:无论如何,对字典视图使用成员资格测试要便宜得多(只需一个方法调用,其他所有操作都是用轻量级对象在C中处理的)。您可以指出,在检查现有字典的值时,无法避免O(N)开销。但是您可以使用其他数据结构来避免它。例如,如果值也是反向字典中的键,那么这将是一个O(1)测试。在某些使用场景中,这可能适合与原始字典一起构建。这不会测试None,而是测试Falsevalues@Jon在大多数情况下,在duck类型的语言中,它不应该这样做,除非显式地需要,这在本例中并不清楚。如果dict包含false,这将中断。
nones = not all(d.values())