Jak dokładnie działa funkcja any () w języku Python?

113

Na stronie z dokumentacją języka Python anyodpowiadający kod any()funkcji jest podany jako:

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

Skąd ta funkcja wie, jaki element chcę przetestować, jeśli nazwij go w tej formie?

any(x > 0 for x in list)

Z definicji funkcji widzę tylko to, że przekazuję obiekt iterowalny. Skąd forpętla wie, że czegoś szukam > 0?

pythoniku
źródło

Odpowiedzi:

166

Jeśli używasz any(lst), widzisz, że lstjest to iterowalne, czyli lista niektórych elementów. Gdyby zawierał [0, False, '', 0.0, [], {}, None](wszystkie mają wartości logiczne False), to any(lst)byłoby False. Gdyby lstzawierał również którykolwiek z następujących elementów [-1, True, "X", 0.00001](z których wszystkie mają wartość True), to any(lst)byłoby True.

W opublikowanym kodzie x > 0 for x in lstjest to inny rodzaj iterowalnej, zwany wyrażeniem generatora . Przed wyrażenia generatorów dodano do Pythona, byś stworzył listowych , która wygląda bardzo podobnie, ale z otoczeniem []„s [x > 0 for x in lst]. Od lstzawierający [-1, -2, 10, -4, 20], co można uzyskać to pojętej listy : [False, False, True, False, True]. Ta wewnętrzna wartość zostanie następnie przekazana do anyfunkcji, która zwróci True, ponieważ istnieje co najmniej jedna Truewartość.

Ale dzięki wyrażeniom generatora Python nie musi już tworzyć tej wewnętrznej listy True(s)i False(s), wartości będą generowane, gdy anyfunkcja iteruje po wartościach generowanych pojedynczo przez wyrażenie generatora. A ponieważ anywystąpią zwarcia, zatrzyma iterację, gdy tylko zobaczy pierwszą Truewartość. Byłoby to szczególnie przydatne, gdybyś utworzył lstcoś w rodzaju lst = range(-1,int(1e9))(lub xrangejeśli używasz Python2.x ). Nawet jeśli to wyrażenie będzie generować ponad miliard wpisy, anyma tylko iść tak daleko, jak w trzecim wejściu, gdy robi się 1, rozpoznawaną Truena x>0, a więc anymoże powrócić True.

Gdybyś utworzył listę składaną , Python musiałby najpierw utworzyć listę miliardów elementów w pamięci, a następnie przekazać ją do any. Ale używając wyrażenia generatora , możesz mieć wbudowane funkcje Pythona, takie jak anyi allprzerywane wcześnie, gdy tylko zostanie zauważona wartość Truelub False.

PaulMcG
źródło
25
Warto również wspomnieć, że any(x > 0 for x in list)jest to tylko cukier syntaktyczny any((x > 0 for x in list)).
georg
3
Powinieneś dodać Nonedo listy elementów, które mają wartości boolowskieFalse
Alok Mysore
2
Dodając do @georg, cukier syntaktyczny nie jest wyjątkowy any. def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
industryworker3595112
@georg Dziękuję za to wyjaśnienie. To jest naprawdę ważny punkt, który mnie pomylił podczas testowania kodu z jakimikolwiek nawiasami.
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

Po prostu zredukuj kilka linii kodu w jedną. Nie musisz pisać długiego kodu, takiego jak:

for n in names:
    if n in 'King and john':
       print True
    else:
       print False
Pranjay Kaparuwan
źródło
23

(x > 0 for x in list) w tym wywołaniu funkcji tworzy wyrażenie generatora np.

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


True
True
False
True
False

Który anyużywa i zwarcia przy napotkaniu pierwszego obiektu, który oceniaTrue

jamylak
źródło
7

To dlatego, że iterowalność jest

(x > 0 for x in list)

Zwróć uwagę, że x > 0zwraca albo Truelub, Falsewięc masz iterowalną wartość logiczną.

kapryśny
źródło
7

Mówiąc prosto, any () działa tak: zgodnie z warunkiem, nawet jeśli napotka jedną spełniającą wartość na liście, zwraca true, w przeciwnym razie zwraca false.

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
Alisha
źródło