¿Todos (lista) usan evaluación de cortocircuito?

Deseo usar la función Python all() para ayudarme a calcular algo, pero este algo podría tardar mucho más tiempo si el all() no se evalúa tan pronto como llega a False . Creo que es probable que se evalúe en corto circuito, pero solo quería asegurarme. Además, ¿hay alguna forma de saber en Python cómo se evalúa la función?

Sí, cortocircuitos:

 >>> def test(): ... yield True ... print('one') ... yield False ... print('two') ... yield True ... print('three') ... >>> all(test()) one False 

De los documentos :

Devuelva Verdadero si todos los elementos del iterable son verdaderos (o si el iterable está vacío). Equivalente a:

 def all(iterable): for element in iterable: if not element: return False return True 

Así que cuando return s Falso, la función se interrumpe de inmediato.

Sí, all utilizan la evaluación de cortocircuito. Por ejemplo:

 all(1.0/x < 0.5 for x in [4, 8, 1, 0]) => False 

Lo anterior se detiene cuando x alcanza 1 en la lista, cuando la condición se vuelve falsa. Si no all estuvieran en cortocircuito, obtendríamos una división por cero cuando x alcanzara 0 .

En respuesta a su pregunta de si puede decirle a all que se evalúen o no un cortocircuito, se trata de un cortocircuito por defecto, pero si desea que no lo sea, puede hacer esto:

 result = all(list(iterable)) 

Aunque eso tiene la propiedad posiblemente indeseable de que toda la lista se cargará en la memoria. No puedo pensar cómo evitarías eso, aparte de usar una función diferente a todas. Por ejemplo

 result = reduce(lambda x,y: x and y, iterable) result = min(iterable) # surprisingly similar to all; YMMV if iterable contains non-booleans 

Asegúrate de no hacer lo que hice al principio, que era tratar de usar cortocircuitos para probar la existencia de un método antes de llamarlo:

 >>> class MyClass(object): ... pass ... >>> a=MyClass() >>> all([hasattr(a,'b'), ab()]) Traceback (most recent call last): File "", line 1, in  AttributeError: 'MyClass' object has no attribute 'b' 

pero

 >>> a=MyClass() >>> hasattr(a,'b') and ab() #doesn't evaluate ab() as hasattr(a,'b') is false False 

En el primer fragmento de código, Python evalúa la lista antes de pasarla a all (), por lo que todavía lanza la excepción. Esto es básicamente lo mismo que usar list () para forzar a todos () a no usar la evaluación de cortocircuito como en la respuesta de morningstar