Come funziona esattamente la funzione python any ()?


113

Nella pagina dei documenti di Python per any, il codice equivalente per la any()funzione è dato come:

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

Come fa questa funzione a sapere quale elemento voglio testare se lo chiamo in questa forma?

any(x > 0 for x in list)

Dalla definizione della funzione, tutto quello che posso vedere è che sto passando un oggetto iterabile. Come fa il forloop a sapere che sto cercando qualcosa > 0?

Risposte:


166

Se usi any(lst)vedi che lstè l'iterabile, che è un elenco di alcuni elementi. Se contenesse [0, False, '', 0.0, [], {}, None](che hanno tutti valori booleani di False) allora any(lst)sarebbe False. Se lstcontenesse anche uno dei seguenti [-1, True, "X", 0.00001](tutti valutati True) allora any(lst)sarebbe True.

Nel codice che hai pubblicato, x > 0 for x in lstquesto è un diverso tipo di iterabile, chiamato espressione generatore . Prima di espressioni generatore sono state aggiunte a Python, si sarebbe creata una comprensione lista , che sembra molto simile, ma con circostante []s': [x > 0 for x in lst]. Dal lstcontenente [-1, -2, 10, -4, 20], si otterrebbe questa lista compreso : [False, False, True, False, True]. Questo valore interno verrebbe quindi passato alla anyfunzione, che restituirà True, poiché è presente almeno un Truevalore.

Ma con le espressioni del generatore , Python non deve più creare quell'elenco interno di True(s)e False(s), i valori verranno generati mentre la anyfunzione itera attraverso i valori generati uno alla volta dall'espressione del generatore. E , poiché va in anycortocircuito, smetterà di iterare non appena vede il primo Truevalore. Ciò sarebbe particolarmente utile se hai creato lstusando qualcosa di simile lst = range(-1,int(1e9))(o xrangese stai usando Python2.x ). Anche se questa espressione genererà oltre un miliardo di voci, anyha solo andare per quanto riguarda la terza voce quando si arriva al 1, che valuta Trueper x>0, e così anypuò tornare True.

Se avessi creato una lista di comprensione , Python avrebbe dovuto prima creare la lista di miliardi di elementi in memoria, e poi passarla a any. Ma usando un'espressione del generatore , puoi fare in modo che le funzioni incorporate di Python piacciano anye si allaprano presto, non appena viene visualizzato un valore Trueo False.


25
Vale anche la pena ricordare che any(x > 0 for x in list)è solo uno zucchero sintattico per any((x > 0 for x in list)).
georg

3
Dovresti aggiungere Noneall'elenco degli elementi che hanno valori booleani diFalse
Alok Mysore

2
Aggiungendo a @georg, lo zucchero sintattico non è speciale any. def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
industryworker3595112

@georg Grazie per questo chiarimento. Questo è un punto davvero importante che mi ha confuso durante il test del codice con qualsiasi parentesi.
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

Riduce solo diverse righe di codice in una. Non devi scrivere codice lungo come:

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

23

(x > 0 for x in list) in quella funzione la chiamata crea un'espressione del generatore es.

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


True
True
False
True
False

Che anyutilizza e cortocircuiti quando si incontra il primo oggetto che valutaTrue


7

È perché l'iterabile è

(x > 0 for x in list)

Nota che x > 0restituisce o Trueo Falsee quindi hai un iterabile di booleani.


7

Semplicemente dicendo, any () fa questo lavoro: in base alla condizione, anche se incontra un valore soddisfacente nell'elenco, restituisce vero, altrimenti restituisce 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.