python - 检查dict的任何值是不是不是None(没有迭代器)
Posted
技术标签:
【中文标题】python - 检查dict的任何值是不是不是None(没有迭代器)【英文标题】:python - check if any value of dict is not None (without iterators)python - 检查dict的任何值是否不是None(没有迭代器) 【发布时间】:2015-11-24 14:57:53 【问题描述】:我想知道是否有可能获得与此代码相同的输出:
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 循环迭代器或生成器?
【问题讨论】:
如果不对其进行迭代,您将无法检查列表中的值.. 你需要检查所有的值;循环到底有什么问题? 您不需要列表理解。只是any(d.values())
。但这在内部循环。没有办法避免这种情况。
罗伯特,看看哈希表是如何工作的(并且是)。你可能会在那里找到你要找的东西。 ***.com/questions/327311/…
为什么这个问题被如此糟糕地否决了?
【参考方案1】:
您可以使用dictionary view 让 Python 在 C 代码中执行循环;这将对所有值进行成员资格测试,而不创建新列表:
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()
测试一样,这使得这是一个 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) 时间内。
【讨论】:
any(map(lambda x: x is not None, d.values()))
在 Python 3 中效率更高,在 Python 2 中也可以使用,怎么样?
@NiklasR:x is None
,当然。 lambda
通话也有成本,我不太确定这样做是否值得。
@NiklasR 这比使用 python3 变体(使用values()
)更糟糕,这将在 Python 2 中创建一个丑陋的列表,然后在生成器表达式中使用它而不是你的最终循环两次,创建一个额外的列表,从而浪费更多。
您可以指出,在检查现有字典的值时,无法避免 O(N) 成本。但是您可以使用其他数据结构来避免它。例如,如果这些值也是反向字典中的键,那么这将是一个 O(1) 测试。在某些使用场景中,这可能适合与原始字典一起构建。
@strubbly:这也是一个好主意,并且可能是 OP 所说的 X 到 Y 问题。【参考方案2】:
你可以使用
nones = not all(d.values())
如果所有值都不是 None,则 nones 将设置为 False,否则设置为 True。虽然它只是一个抽象,但在内部它必须遍历值列表。
【讨论】:
这不测试 None,它测试 False-like 值 @Jon 在大多数情况下,在鸭式语言中,它不应该是必须的,除非明确需要,在这种情况下不清楚。 如果 dict 包含 False,这将中断。以上是关于python - 检查dict的任何值是不是不是None(没有迭代器)的主要内容,如果未能解决你的问题,请参考以下文章