2015-05-21 17 views
5
def partition(n, iterable): 
    p = izip_longest(*([iter(iterable)] * n)) 
    r = [] 
    for x in p: 
     print(x) #I added this 
     s = set(x) 
     s.discard(None) 
     r.append(list(s)) 
    return r 

To jest właściwie praca, która została zamieszczona na SO i jest nowicjuszem. Myślałem, że to interesujące. Więc masz wyjścia jak następuje:Do czego służy ta funkcja? (Python iterators)

partition(5, L) 
(1, 2, 3, 4, None) 
Out[86]: [[1, 2, 3, 4]] 

Dla mnie to już jest mylące, ponieważ myślałem izip_longest(*([iter(iterable)] * n)) by uruchomić funkcję izip_longest na liście n identycznych iteratorów więc spodziewałem się pierwsze wyjście z (1,1,1,1,1) a potem wyjście z (2,2,2,2,2) i tak dalej.

tak krótka wersja moje pytanie, jest to, co dzieje się z tej linii:

p = izip_longest(*([iter(iterable)] * n)) 

Przetwarzanie to bym myślał [iter (iterable)] * n tworzy listę długości n identycznych iterables wszystkich wskazując na to samo - tak robi się z linii poleceń, ale nie wydaje się, żeby to było to, co tu robi, na podstawie wydruków wydrukowanych powyżej.

Również myślałem, że * na początku ...longest(*... był tam, ponieważ lista ma nieznaną długość, ale nie sądzę, że to ma sens. Co to jest pierwszy symbol * podczas wywoływania funkcji? Nie wygląda na to, że po prostu wskazuje na nieznaną długość listy argumentów ...

Tak więc pod koniec dnia jestem kompletnie zagubiony. Czy ktoś może przeprowadzić mnie przez tę składnię?

Wielkie dzięki za wszelkie dane wejściowe!


Dziękuję za wszystkie pomocne odpowiedzi, wszystkim. Nie jestem pewien, czy zajmuję się tutaj odpowiedzią lub pytaniem, ale wydaje mi się, że ta lista będzie rozumiała to samo dla list i krotek (zdaję sobie sprawę, że iteratory miałyby zastosowanie również do słowników, klas niestandardowych, innych rzeczy ... .)

[L[i*n:(i+1)*n] for i in range(int(ceil(len(L)/float(n)))) ] 
+1

Czytałeś [Jak 'zip (* [iter (s)] * n)' praca w Pythonie] (http://stackoverflow.com/questions/2233204/how- does-zipitersn-work-in-python)? –

+0

łamie dużą listę na N mniejszych list .... wypełniając Brak w przypadku, gdy długość listy nie jest podzielna równomiernie przez N ... jedyną podlistą, która powinna zawierać dowolne "Brak" jest ostatnia lista –

+0

Dodaj 'print (list (p))', aby zobaczyć, co zrobił 'izip_longest()'. – martineau

Odpowiedz

6

Dane:

>>> li 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 

Jest wspólny język Pythona z użyciem zip w połączeniu z iter i * operator w celu podzielenia listy płaskiej listy na listę list o długości n:

>>> n=3 
>>> zip(*([iter(li)] * n)) 
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 14), (15, 16, 17), (18, 19, 20)] 

Jednak jeśli n nie jest nawet wielokrotnością długości, ostateczna lista jest obcięty:

>>> n=4 
>>> zip(*([iter(li)] * n)) 
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15), (16, 17, 18, 19)] 

Można użyć izip_longest użyć pełną listę wypełniony z wybraną wartość dla niepełne wykazy sub:

>>> list(izip_longest(*([iter(li)] * n))) 
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15), (16, 17, 18, 19), (20, None, None, None)] 
+0

dobra odpowiedź na wyjaśnienie, dlaczego dostał Brak i dlaczego jego używanie izip_longest :) +1 –

+0

@ dziękuję dzięki dużo. To naprawdę miłe. – sunny

+1

Należy zauważyć, że ze względu na sposób, w jaki dodatkowe 'None's są usuwane, iterables zawierające' None' nie są obsługiwane przez tę funkcję. Na przykład 'partition (2, [1,2, None, 4,5])' daje '[[1, 2], [4], [5]]'. Byłoby bardziej odporne na używanie niestandardowej wartości wartownika, jak sądzę. – jpmc26

6

iter(my_list) konwertuje listę w produkt iterable (czyli taki, w którym elementy są spożywane jak są one postrzegane)

[my_iter]*5 tworzy nową listę [my_iter,my_iter,my_iter,my_iter,my_iter] w których wszystkie Skieruj my_iter „s do tego samego dokładna iteracyjnej

zip(*[my_iter,my_iter,my_iter,my_iter,my_iter]) 

jest taka sama jak

zip(my_iter,my_iter,my_iter,my_iter,my_iter) 

(the ikona prostu rozpakowuje się lista/krotki), który w zasadzie tylko zwraca 5xlen(my_list)//5 2d listy

można uprościć go z normalnego zip

#this method will have no `None` entries 
new_list_partitioned = zip(*[iter(big_list)]*N) + [big_list[-(len(big_list)%N):],] 
+0

jeśli spojrzysz na moje pytanie, ta część mam. To, czego nie dostałem, to dlaczego * przed [iter (... – sunny

+0

rozpakowuje listę ... –