Python: parece que no funciona comprobar si un 'Diccionario' está vacío

396

Estoy tratando de verificar si un diccionario está vacío pero no se comporta correctamente. Simplemente lo omite y muestra EN LÍNEA sin nada más que mostrar el mensaje. Alguna idea de por qué?

 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())) 
Despiadado
fuente
66
Para verificar si self.usersno está vacío, solo hazlo if self.users.
BrenBarn
44
Su isEmptyrealidad devuelve Truesi la primera clave, producido a partir del diccionario es truey y vuelve Falseotra manera. Si el diccionario está vacío, devuelve el Noneque no lo está == False.
Hyperboreus
Su declaración if es al revés.
Físico loco
tenga cuidado con las teclas falsas stackoverflow.com/a/17347421/1379762
Wajih

Respuestas:

737

Los diccionarios vacíos evalúanFalse en Python:

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

Por lo tanto, su isEmptyfunción es innecesaria. Todo lo que necesitas hacer es:

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()))

fuente
77
@Wajih que vinculas es irrelevante: bool({False: False})aún se evalúa True. El enlace que proporcionó corresponde al anymétodo, que depende de las claves.
Ulysse BN
@Wajih, ¿qué significa eso?
Charlie Parker
2
Siento que 'no dict' no es explícito
imbatman el
De acuerdo, tengo ganas de usar los booleanos y not <dict>no está tan claro también
cryanbhu
130

Aquí hay tres formas de verificar si dict está vacío. Sin embargo, prefiero usar la primera manera. Las otras dos formas son demasiado prolijas.

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"
doble
fuente
44
Suspiro ... a todo el mundo le gusta ser "pitón" y elige el menor número de caracteres. Primero, otro criterio es la legibilidad. En segundo lugar, la primera prueba en la respuesta anterior es verdadera no solo si el dict existe y está vacío, sino también si test_dict es None. Utilice esta prueba solo cuando sepa que el objeto dict existe (o cuando la diferencia no importa). La segunda forma también tiene ese comportamiento. Solo la tercera forma ladra si test_dict es None.
Andreas Maier
1
@AndreasMaier Exactamente mi sentimiento también. Además, python se escribe dinámicamente. Dentro de una función es común verificar "si x es un diccionario no vacío, luego haga esto; si x es una matriz numpy no vacía, entonces haga eso". Entonces, el primer código fallará if xcuando x sea una matriz
numpy
1
@Wajih su enlace sigue siendo irrelevante aquí ... Vea por qué
Ulysse BN
1
No votar esto aunque es técnicamente correcto debido a las preocupaciones con las que comparto. @AndreasMaier
Stunner
16
dict = {}
print(len(dict.keys()))

si la longitud es cero significa que dict está vacío

Achilles Ram Nakirekanti
fuente
3
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código.
DimaSan
1
len(dict.keys())es equivalente alen(dict)
pdpAxis
@pdpAxis En el valor que da, aunque apuesto a que la implementación dict.__len__es probablemente un poco más rápida. :)
Mateen Ulhaq
6

A continuación se muestran formas simples de verificar un dict vacío:

        a= {}

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

Aunque el primer método es más estricto que cuando a = Ninguno, el método 1 proporcionará un resultado correcto, pero el método 2 dará un resultado incorrecto.

Shagun Pruthi
fuente
1

Un diccionario se puede convertir automáticamente a booleano, que se evalúa como Falsepara diccionario vacío y Truepara diccionario no vacío.

if myDictionary: non_empty_clause()
else: empty_clause()

Si esto parece demasiado idiomático, también puede probar len(myDictionary)cero o set(myDictionary.keys())un conjunto vacío, o simplemente probar la igualdad con {}.

La función isEmpty no solo es innecesaria, sino que su implementación tiene múltiples problemas que puedo detectar a primera vista.

  1. La return Falsedeclaración está sangrada un nivel demasiado profundo. Debe estar fuera del ciclo for y al mismo nivel que la forinstrucción. Como resultado, su código procesará solo una clave, seleccionada arbitrariamente, si existe una clave. Si no existe una clave, la función volverá None, que se convertirá en booleano False. ¡Ay! Todos los diccionarios vacíos se clasificarán como falsos negativos.
  2. Si el diccionario no está vacío, el código procesará solo una clave y devolverá su valor emitido a booleano. Ni siquiera puede suponer que se evalúa la misma clave cada vez que la llama. Entonces habrá falsos positivos.
  3. Digamos que corrige la sangría de la return Falsedeclaración y la forsaca del ciclo. Entonces, lo que obtienes es el OR booleano de todas las claves, o Falsesi el diccionario está vacío. Aún así tendrás falsos positivos y falsos negativos. Haga la corrección y pruebe contra el siguiente diccionario en busca de evidencia.

myDictionary={0:'zero', '':'Empty string', None:'None value', False:'Boolean False value', ():'Empty tuple'}

Della
fuente
-1

También puedes usar get (). Inicialmente creía que solo verificaba si existía la clave.

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

Lo que me gusta de get es que no desencadena una excepción, por lo que es fácil atravesar grandes estructuras.

MortenB
fuente
-4

¿Por qué no usar la prueba de igualdad?

def is_empty(my_dict):
    """
    Print true if given dictionary is empty
    """
    if my_dict == {}:
        print("Dict is empty !")
wieczorek1990
fuente
Parece un error de sintaxis y no muestra cómo aplicar la verificación en el contexto de la pregunta.
Roland Weber
-7

usar cualquier'

dict = {}

if any(dict) :

     # true
     # dictionary is not empty 

else :

     # false 
     # dictionary is empty
Chhotu Sardar
fuente
44
anycomprueba si el dict contiene alguna clave verdadera, por ejemplo, any({0: 'something'})regresa Falseaunque el dict no esté vacío
Railslide
Sí, para salvar de ambos casos, verdadero y en blanco, otro bool sabio habría dado verdadero para el caso verdadero. si piensas en un propósito de codificación general.
chhotu sardar