¿Cómo funciona exactamente la función any () de Python?


113

En la página de documentos de Python para any, el código equivalente para la any()función se da como:

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

¿Cómo sabe esta función qué elemento quiero probar si lo llamo de esta forma?

any(x > 0 for x in list)

De la definición de la función, todo lo que puedo ver es que estoy pasando un objeto iterable. ¿Cómo sabe el forbucle que estoy buscando algo > 0?

Respuestas:


166

Si lo usa any(lst), verá que lstes el iterable, que es una lista de algunos elementos. Si contuviera [0, False, '', 0.0, [], {}, None](que todos tienen valores booleanos de False), entonces any(lst)sería False. Si lsttambién contiene alguno de los siguientes [-1, True, "X", 0.00001](todos los cuales se evalúan True), entonces any(lst)sería True.

En el código que publicaste, x > 0 for x in lsteste es un tipo diferente de iterable, llamado expresión generadora . Antes de las expresiones generadoras se añadieron a Python, se habría creado una lista por comprensión , que es muy similar, pero con rodea []'s: [x > 0 for x in lst]. Del lstcontiene [-1, -2, 10, -4, 20], se llega a esta lista comprendido : [False, False, True, False, True]. Este valor interno luego se pasaría a la anyfunción, que regresaría True, ya que hay al menos un Truevalor.

Pero con las expresiones generadoras , Python ya no tiene que crear esa lista interna de True(s)y False(s), los valores se generarán a medida que la anyfunción itera a través de los valores generados uno a la vez por la expresión generadora. Y , dado que hay anycortocircuitos, dejará de iterar tan pronto como vea el primer Truevalor. Esto sería especialmente útil si creó lstusando algo como lst = range(-1,int(1e9))(o xrangesi está usando Python2.x ). A pesar de que esta expresión generará más de mil millones entradas, anysólo tiene que ir hasta la tercera entrada cuando se llega a 1, que evalúa Truepara x>0, y así anypuede volver True.

Si hubiera creado una lista de comprensión , Python primero habría tenido que crear la lista de mil millones de elementos en la memoria y luego pasarla a any. Pero al usar una expresión generadora , puede hacer que las funciones integradas de Python como anyy allsalgan temprano, tan pronto como se vea un valor Trueo False.


25
También vale la pena mencionar que any(x > 0 for x in list)es solo un azúcar sintáctico para any((x > 0 for x in list)).
georg

3
Debe agregar Nonea la lista de elementos que tienen valores booleanos deFalse
Alok Mysore

2
Agregando a @georg, el azúcar sintáctico no es especial para any. def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
industryworker3595112

@georg Gracias por esta aclaración. Este es un punto realmente importante que me confundió al probar el código con cualquier paréntesis.
MasayoMusic

39
>>> names = ['King', 'Queen', 'Joker']
>>> any(n in 'King and john' for n in names)
True

>>> all(n in 'King and Queen' for n in names)
False

Simplemente reduce varias líneas de código en una. No tiene que escribir un código extenso como:

for n in names:
    if n in 'King and john':
       print True
    else:
       print False

23

(x > 0 for x in list) en esa función, la llamada crea una expresión generadora, por ejemplo.

>>> nums = [1, 2, -1, 9, -5]
>>> genexp = (x > 0 for x in nums)
>>> for x in genexp:
        print x


True
True
False
True
False

Que anyutiliza y cortocircuitos al encontrar el primer objeto que evalúaTrue


7

Es porque lo iterable es

(x > 0 for x in list)

Tenga en cuenta que x > 0devuelve Trueo Falsey, por lo tanto, tiene un iterable de booleanos.


7

Simplemente diciendo, any () hace este trabajo: de acuerdo con la condición, incluso si encuentra un valor satisfactorio en la lista, devuelve verdadero, de lo contrario devuelve falso.

list = [2,-3,-4,5,6]

a = any(x>0 for x in lst)

print a:
True


list = [2,3,4,5,6,7]

a = any(x<0 for x in lst)

print a:
False
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.