Python中检查空字典和空值的惯用方式

6

我正在使用这些字典,它们可以是完全空的,比如collection_a,或包含一个单层嵌套的可能为空的字典。它不会有更多的层级。

collection_a = {}
collection_b = {"test": {}}

print is_empty(collection_a)
print is_empty(collection_b)

def is_empty(collection):
    return not all(collection.values())

或者

def is_empty(collection):
    return not bool(collection.values())

有没有一种唯一的方法来检查a或b是否具有值?

您可以检查all(collection_b.values()),但对于collection_a,它将返回True,因此不起作用。

您还可以检查bool(collection_a.values()),但对于collection_b,它将返回True,因此也不起作用...

有没有一种包含两种情况的独特方法?


我的意思是我想在同一个条件下包含两种情况。 - lapinkoira
你能解释一下为什么要这样做吗?背景是什么? - Chris_Rands
4
这真的感觉像一个XY问题。而且在我看来,问题仍然不够清晰明了。 - Lafexlos
1
@lapinkoira。如果您能满足澄清请求,您可能会得到更好的答案。 - Mad Physicist
在我的代码中,我使用了可能完全为空的字典和其他可能具有嵌套字典也为空的字典,没有其他类型的字典,我试图避免双重检查,我认为使用我在问题中写的all()或bool(),但它只适用于其中一个,从未同时适用于两个。 - lapinkoira
显示剩余9条评论
4个回答

12

由于空字典为falsy,因此测试任何内容都可以:

>>> collection_a = {}
>>> collection_b = {"test": {}}
>>> any(collection_a.values())
False
>>> any(collection_b.values())
False

这假定字典的值始终为字典。


3
不清楚这个代码对于其他假值是否能正常运行,例如 collection_c = {3:0} - Chris_Rands
2
@Chris_Rands。我认为OP的意思是,如果有什么的话,第一级的值将始终是“dict”。 - Mad Physicist
1
@Chris_Rands 我没有使用那种字典,所以看起来 "any" 可以工作,我没有使用它是因为认为如果 "all" 不起作用,"any" 也不会起作用,但是现在它正在工作。 - lapinkoira

6

如果您想检查字典是否具有值,并且(如果有)所有值是否“真实”,只需将两个测试组合起来:

bool(collection) and all(collection.values())

在第一部分中,bool是可选的,但如果没有它,当字典为空时你会得到一个不直观的{}
当然,如果你只想检查集合中的任何一个值是否为“真值”(这点从你的问题中并不完全清楚),你只需要执行any(collection),如其他答案中已经提到的;这同时也会检查集合是否非空。

那应该是一个 any - Mad Physicist
@MadPhysicist,不,按我理解这个问题应该真正成为一个“全部”。 - tobias_k
1
@Vinny,你在哪里看到它对于0值应该如何行为?鉴于OP使用了“all”,我认为这就是他想要的,他只是在寻找一种使其对于空集合返回False的方法。但当然,这只是我对问题的理解。 - tobias_k
@tobias_k。有趣的观点。OP的代码说“all”,但我读到的单词意味着“any”。很难确定哪一个是正确的。 - Mad Physicist
@tobias_k. OP发表了一个新评论,意味着外部字典中只有一个键。我们的解决方案可能是等价的... - Mad Physicist
显示剩余2条评论

3

因为:

>>> dict={}
>>> not dict
True

所以你可以像这样检查:

如此,您可以像这样进行检查:

collection_a = {"hello":1,"bye":2}
if collection_a:
    #do your stuff
    print("not empty")

collection_a = {}
if collection_a:
    print("dict is not empty")

如果您想检查字典a或字典b,则:

if collection_a or collection_b:
    print("not empty")

1

或者,与 more-itertools' collapse() 结合使用的 bool()

import more_itertools

def has_value(thing):
    return bool(*more_itertools.collapse(thing))

>>> has_value({})
False
>>> has_value({''})
False
>>> has_value({0:['']})
False
>>> has_value({'test':[]})
True

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接