如何检查字典是否为空?

673
我正在尝试检查一个字典是否为空,但它的行为不正常。它只是跳过它并显示ONLINE,除了显示这条消息外没有任何其他东西。有任何想法吗?
def isEmpty(self, dictionary):
    for element in dictionary:
        if element:
            return True
        return False

def onMessage(self, socket, message):
    if self.isEmpty(self.users) == False:
        socket.send("Nobody is online, please use REGISTER command" \
                 " in order to register into the server")
    else:
        socket.send("ONLINE " + ' ' .join(self.users.keys()))    

8
要检查self.users是否非空,只需执行if self.users即可。 - BrenBarn
4
如果从字典中产生的第一个键为真值,您的isEmpty实际上会返回True,否则返回False。如果字典为空,则返回None,它不等于False - Hyperboreus
你的if语句是反过来的。 - Mad Physicist
小心假键(false-like keys)。https://dev59.com/BWYr5IYBdhLWcg3w6OGd#17347421 - Wajih
可能是Python:检查字典是否为空的有效方法的重复问题。 - tripleee
额,.join(...) 是指 socket.join(...) 吗?这是合法的语法吗?如果是的话,我宁愿避免使用它,但如果有相关文档,我仍然很感兴趣了解更多。额,算了吧...这是字符串连接 :D - Nolo
8个回答

1167

在Python中,空字典会被判定为False

>>> dct = {}
>>> bool(dct)
False
>>> not dct
True
>>>

因此,您的isEmpty函数是不必要的。您只需要这样做:
def onMessage(self, socket, message):
    if not self.users:
        socket.send("Nobody is online, please use REGISTER command" \
                    " in order to register into the server")
    else:
        socket.send("ONLINE " + ' ' .join(self.users.keys()))

7
@Wajih,你提供的链接与问题无关:“bool({False: False})”仍会评估为“True”。你提供的链接是针对取决于键的“any”方法的。 - Ulysse BN
1
@Wajih 这是什么意思? - Charlie Parker
7
我觉得“not dict”不够明确。 - imbatman
2
同意,我觉得使用布尔值和“not <dict>”也不是很清晰。 - cryanbhu
1
你的isEmpty函数是不必要的,但它确实使代码更易于理解。 - GG.
显示剩余3条评论

219

以下有三种方法可以检查字典是否为空。尽管另外两种方法过于冗长,但我更喜欢仅使用第一种方法。

test_dict = {}

if not test_dict:
    print "Dict is Empty"


if not bool(test_dict):
    print "Dict is Empty"


if len(test_dict) == 0:
    print "Dict is Empty"

104
叹气...每个人都喜欢变得"pythonic"并且使用最少的字符进行编码。首先,另一个标准是可读性。其次,在上面的答案中,第一个测试条件不仅在字典存在且为空时成立,而且在test_dict为None时也成立。因此,只有在您知道字典对象存在(或差异不重要时)时才使用此测试。第二种方法也具有这种行为。只有第三种方法在test_dict为None时会出现问题。 - Andreas Maier
1
@AndreasMaier 我也有同样的感觉。此外,Python 是动态类型语言。在函数内部,通常会检查“如果 x 是非空字典,则执行此操作;如果 x 是非空 numpy 数组,则执行那个操作”。然后,当 x 是 numpy 数组时,第一段代码将在 if x 处失败。 - jf328
1
@Wajih,你的链接在这里仍然不相关...请看为什么 - Ulysse BN
3
尽管从技术上讲是正确的,但因为我与@AndreasMaier分享的担忧,我不会点赞这个。 - Stunner
@AndreasMaier,解决这个问题的Pythonic方式是在开头添加if test_dict is not None: print("Dict is None") - undefined

36
d = {}
print(len(d.keys()))

长度为零意味着字典为空。


5
虽然这段代码可能解决了问题,但是包含解释真的有助于提高您帖子的质量。请记住,您正在回答未来读者的问题,而那些人可能不知道您提供代码建议的原因。 - DimaSan
7
len(dict.keys()) 相当于 len(dict) - pdpAxis
@pdpAxis 在它所提供的值中,尽管我敢打赌 dict.__len__ 的实现可能会更快一些。 :) - Mateen Ulhaq

27

检查空字典的简单方法如下:

a = {}
  1. if a == {}:
      print ('empty dict')
    
  2. if not a:
      print ('empty dict')
    

方法1更加严格,因为当 a = None 时,方法1会提供正确的结果,而方法2会给出错误的结果。


9
一个字典在被自动转换成布尔值时,如果是空字典,则为False,如果是非空字典,则为True
if myDictionary: non_empty_clause()
else: empty_clause()

如果这看起来太习惯用语了,您还可以测试len(myDictionary)是否为零,或者测试一个空集合set(myDictionary.keys()),或者只是使用{}进行相等性测试。
isEmpty函数不仅是不必要的,而且您的实现还存在多个问题,我可以直接发现。
  1. return False语句缩进深度过深。它应该在for循环之外并与for语句处于同一级别。因此,如果存在键,则代码将仅处理一个任意选择的键。如果不存在键,则函数将返回None,该值将被转换为布尔值False。糟糕!所有空字典都将被分类为false-negative。
  2. 如果字典不为空,则代码将仅处理一个键并返回其转换为布尔值的值。您甚至不能假设每次调用时都评估相同的键。因此会有错误的结果。
  3. 假设您更正了return False语句的缩进并将其放在for循环之外。然后您得到的是所有键的布尔OR,如果字典为空,则为False。仍然会出现错误的结果。请对以下字典进行更正并测试证据。
myDictionary={0:'zero', '':'Empty string', None:'None value', False:'Boolean False value', ():'Empty tuple'}

5

第一种方法

len(given_dic_obj) 

如果字典为空则返回0,否则返回字典的大小。

第二种方式

bool(given_dic_object)

如果字典为空,返回False,否则返回True。


你这样理解有误 - bool(given_dic_object) 如果字典是空的话,会返回False。 - Andy
@andy:我没有提到同样的事情吗? - Arpan Saini

0

你也可以使用 get()。 最初我认为它只检查键是否存在。

>>> d = { 'a':1, 'b':2, 'c':{}}
>>> bool(d.get('c'))
False
>>> d['c']['e']=1
>>> bool(d.get('c'))
True

我喜欢使用get的原因是它不会触发异常,因此可以轻松遍历大型结构。


-9
使用 'any'
dict = {}

if any(dict) :

     # true
     # dictionary is not empty 

else :

     # false 
     # dictionary is empty

4
any 函数用于检查字典中是否存在任何真值键,例如 any({0: 'something'}) 返回 False,即使字典不为空。 - Railslide
是的,这样可以同时避免 truthy 和 blank 的情况,否则 bool 会在 truthy 情况下返回 true。如果你考虑一般编码目的的话。 - chhotu sardar

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