2013-05-12 12 views
63

Na stronie docs Pythona do any, kod odpowiednik dla funkcji any() jest podana jako:Jak dokładnie działa funkcja python()?

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

Jak działa ta funkcja, co chcę elementem testu jeśli nazwać to w tej formie?

Z definicji funkcji widzę tylko, że przechodzę przez obiekt iterowalny. W jaki sposób pętla for wie, że szukam czegoś o nazwie > 0?

Odpowiedz

92

Jeśli używasz any(lst) widać, że lst jest iterable, który znajduje się lista niektórych elementów, które. Jeśli zawierał [0, False, '', 0.0, [], {}, None] (wszystkie mają wartości boolowskie False), wówczas any(lst) będzie False. Jeśli lst również zawiera którekolwiek z następujących [-1, True, "X", 0.00001] (wszystkie z nich oceniają na True), wówczas any(lst) będzie True.

W opublikowanym przez Ciebie kodzie, x > 0 for x in lst, jest to inny rodzaj iteracji, nazywany wyrażeniem generującym . Zanim dodaliśmy wyrażeń generatora do Pythona, utworzysz listę ze zrozumieniem listy, która wygląda bardzo podobnie, ale z otoczeniem []: [x > 0 for x in lst]. Od lst zawierającego [-1, -2, 10, -4, 20], otrzymasz tę zrozumiałą listę: [False, False, True, False, True]. Ta wewnętrzna wartość zostanie następnie przekazana do funkcji any, która zwróci wartość True, ponieważ istnieje co najmniej jedna wartość True.

Ale z Generator wyrażeń, Python nie musi już tworzyć tę wewnętrzną listę True(s) i False(s) wartości zostaną wygenerowane jak any funkcyjne iteracji wartości wygenerowany w momencie wyrażenia generatora. i, ponieważ zwarcie, zatrzyma iterację, gdy tylko zobaczy pierwszą wartość True. Byłoby to szczególnie przydatne, jeśli utworzysz lst używając czegoś takiego jak lst = range(-1,int(1e9)) (lub xrange, jeśli używasz Python2.x).Nawet jeśli to wyrażenie wygeneruje ponad miliard wpisów, tylko any musi przejść tylko do trzeciego wpisu, gdy dojdzie do 1, który ocenia True dla x>0, a więc any może zwrócić True.

Jeśli utworzyłeś listę ze zrozumieniem, Python musiałby najpierw utworzyć listę pamięci zawierającą miliard elementów, a następnie przekazać ją do any. Ale używając wyrażenia generatora , możesz mieć wbudowane funkcje Pythona, takie jak any i all, które ulegają przedwczesnemu złamaniu, gdy tylko pojawi się wartość True lub False.

+12

Byłoby również wspomnieć, że 'dowolny (x> 0 dla x na liście)' jest po prostu cukier syntaktyczny dla 'dowolny ((x> 0 dla x w liście)) '. – georg

+3

Powinieneś dodać 'Brak' do listy elementów, które mają wartości logiczne' Fałszywe' –

+0

Dodając do @georg, cukier syntaktyczny nie jest specjalny dla 'any'. 'def b (x): return x; drukuj b (x> 1 dla x w xs) # drukuje industryworker3595112

5

To dlatego, że jest iterable

(x > 0 for x in list) 

Zauważ, że x > 0 powraca albo True lub False a więc masz iterowalny wartości logicznych.

19

(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 

any wykorzystuje i shortcircuits po napotkaniu pierwszego obiektu, który ocenia True

1

Po prostu mówiąc, dowolne() to działa: 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 
15
>>> 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 

To po prostu zmniejszyć kilka linii kodu w jednym. Nie trzeba pisać długich kod jak:

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