Estoy tratando de verificar una serie de condiciones usando la función all() de Python.

Según tengo entendido, este código cortocircuita, así que, tan pronto como evalúa una condición como False, la función también devuelve False. Si esa comprensión es correcta, entonces alguien puede explicar lo siguiente:

>>> a = None
>>> b = None
>>> all([a is None, b])
False
>>> all([a is None, b, "text" in b])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument of type 'NoneType' is not iterable
>>> b = {"text": "Text I'm looking for"}
>>> all([a is None, b, "text" in b])
True

La primera vez que ejecuto all() muestra que se evalúa correctamente a False, entonces ¿por qué, si agrego otra prueba, se rompe? ¿He entendido mal cómo funciona el cortocircuito?

He probado esto en python 3.8.3 y python 2.7.18 con el mismo resultado.

2
elParaguayo 24 jun. 2020 a las 22:40

2 respuestas

La mejor respuesta

Esto no tiene nada que ver con all. Está creando una lista literal, que evaluará su contenido antes de pasarla a all:

>>> [a is None, b, "text" in b]

Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: argument of type 'NoneType' is not iterables

Si desea que esto funcione como espera, necesita una estructura más perezosa que una lista:

a = None
b = None

def lazy():  # A lazy generator
    yield a is None
    yield b
    yield "text" in b

>>> all(lazy())
False
5
Carcigenicate 24 jun. 2020 a las 19:46

Se están realizando evaluaciones de expresiones. Esa es la razón por la que está obteniendo tal salida.

Mira esto:

>>> import dis
>>> def foo(): return all([True, False ,3 == 2])
... 
>>> dis.dis(foo)
  1           0 LOAD_GLOBAL              0 (all)
              2 LOAD_CONST               1 (True)
              4 LOAD_CONST               2 (False)
              6 LOAD_CONST               3 (3)
              8 LOAD_CONST               4 (2)
             10 COMPARE_OP               2 (==)
             12 BUILD_LIST               3
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
2
Vicrobot 24 jun. 2020 a las 19:47