s = [1,2,3,4,5,6,7,8,9]
n = 3
zip(*[iter(s)]*n) # returns [(1,2,3),(4,5,6),(7,8,9)]
Jak działa zip(*[iter(s)]*n)
? Jak by to wyglądało, gdyby było napisane bardziej szczegółowym kodem?Jak działa zip (* [iter (s)] * n) w Pythonie?
s = [1,2,3,4,5,6,7,8,9]
n = 3
zip(*[iter(s)]*n) # returns [(1,2,3),(4,5,6),(7,8,9)]
Jak działa zip(*[iter(s)]*n)
? Jak by to wyglądało, gdyby było napisane bardziej szczegółowym kodem?Jak działa zip (* [iter (s)] * n) w Pythonie?
iter()
to iterator sekwencji. [x] * n
tworzy listę zawierającą n
ilość ilość x
, tj. Listę o długości n
, gdzie każdy element to x
. *arg
rozpakowuje sekwencję argumentów dla wywołania funkcji. Dlatego trzy razy przekazujesz ten sam iterator do zip()
i za każdym razem pobiera element z iteratora.
x = iter([1,2,3,4,5,6,7,8,9])
print zip(x, x, x)
iter(s)
zwraca iterator dla s.
[iter(s)]*n
tworzy listę n razy ten sam iterator dla s.
Tak więc, wykonując zip(*[iter(s)]*n)
, wyodrębnia element ze wszystkich trzech iteratorów z listy w kolejności. Ponieważ wszystkie iteratory są tym samym obiektem, po prostu grupuje listę w kawałkach n
.
Nie "iteratory z tej samej listy", ale "n razy ten sam obiekt iteratora". Różne obiekty iteratora nie współdzielą stanu, nawet jeśli są z tej samej listy. –
Dzięki, poprawione. Rzeczywiście właśnie to "myślałem", ale napisałem coś innego. – sttwister
Inne świetne odpowiedzi i komentarze dobrze wyjaśniają role argument unpacking i zip().
Jak Ignacio i ujukatzel powiedzieć, przekazać do zip()
trzech odniesień do tego samego iteratora i zip()
sprawia, 3-krotki z całkowitymi w porządku-z każdym odniesieniu do iteracyjnej:
1,2,3,4,5,6,7,8,9 1,2,3,4,5,6,7,8,9 1,2,3,4,5,6,7,8,9
^ ^ ^
^ ^ ^
^ ^ ^
a ponieważ prosić o bardziej opisowym próbki kodu:
chunk_size = 3
L = [1,2,3,4,5,6,7,8,9]
# iterate over L in steps of 3
for start in range(0,len(L),chunk_size): # xrange() in 2.x; range() in 3.x
end = start + chunk_size
print L[start:end] # three-item chunks
Następujące wartości start
i end
:
[0:3) #[1,2,3]
[3:6) #[4,5,6]
[6:9) #[7,8,9]
FWIW, można uzyskać ten sam rezultat z map()
z początkowym argument None
:
>>> map(None,*[iter(s)]*3)
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
więcej na zip()
i map()
: http://muffinresearch.co.uk/archives/2007/10/16/python-transposing-lists-with-map-and-zip/
To nie jest trzy kopie tego samego iteratora, to trzy razy ten sam obiekt iteratora :) –
Jedno słowo rady do korzystania zamek ten droga. Obetnie twoją listę, jeśli jej długość nie jest równomiernie podzielna. Aby obejść ten problem, można użyć wartości itertools.izip_longest, jeśli można akceptować wartości wypełnienia.Lub można użyć coś takiego:
def n_split(iterable, n):
num_extra = len(iterable) % n
zipped = zip(*[iter(iterable)] * n)
return zipped if not num_extra else zipped + [iterable[-num_extra:], ]
wykorzystania:
for ints in n_split(range(1,12), 3):
print ', '.join([str(i) for i in ints])
Drukuje:
1, 2, 3
4, 5, 6
7, 8, 9
10, 11
To jest już udokumentowane w przepisach 'itertools': http://docs.python.org/2/library/itertools.html#recipes' grouper'. Nie trzeba wymyślać na nowo koła – jamylak
myślę o jednej rzeczy, która jest nieodebrane we wszystkich odpowiedzi (chyba oczywiste dla tych, którzy znają iteratory), ale nie tak oczywiste dla innych jest -
Ponieważ mamy ten sam iterator, dostaje s skonsumowane, a pozostałe elementy są używane przez zip. Więc jeśli po prostu użyliśmy listy, a nie iteracji, np. .
l = range(9)
zip(*([l]*3)) # note: not an iter here, the lists are not emptied as we iterate
# output
[(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6), (7, 7, 7), (8, 8, 8)]
Korzystanie iterator, wyskakuje wartości i tylko utrzymuje pozostały dostępne, więc na zamek po 0 jest zużywana 1 jest dostępna, a następnie 2 i tak dalej. Bardzo subtelna rzecz, ale całkiem sprytna !!!
+1, Uratowałeś mnie! Nie mogę uwierzyć, że inne odpowiedzi pominęły ten ważny szczegół, zakładając, że wszyscy o tym wiedzą. Czy możesz podać jakiekolwiek odniesienie do dokumentacji, która zawiera te informacje? –
również zajrzeć tutaj, gdzie to działa, jest również wyjaśnione: http://stackoverflow.com/questions/2202461/yield-multiple-objects-at-a-time- from-an-iterable-object/2202485# 2202485 –
jeśli odpowiedzi tutaj są niewystarczające, to blogowałem to tutaj: http://telliott99.blogspot.com/2010/01/chunks-of-sequence-in-python.html – telliott99
Chociaż bardzo intrygujące, ta technika musi być skierowana przeciwko podstawowa "czytelność" wartości Pythona! – Demis