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)]
Как делает zip(*[iter(s)]*n)
работа? На что было бы похоже, было ли это записано с большим количеством подробного кода?
iter ()
- итератор над последовательностью. [x] * n
создает список, содержащий n
количество x
, то есть список длиной n
, где каждый элемент равен х
. * arg
распаковывает последовательность в аргументы для вызова функции. Поэтому вы передаете один и тот же итератор 3 раза в zip ()
, и он каждый раз извлекает элемент из итератора.
x = iter([1,2,3,4,5,6,7,8,9])
print zip(x, x, x)
Другие отличные ответы и комментарии хорошо объясняют роль распаковки аргументов и zip () .
Как говорят Игнасио и ujukatzel , вы передаете в zip ()
три ссылки на один и тот же итератор, а zip ()
делает 3-кортежи целых чисел - по порядку - из каждой ссылки на итератор:
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
^ ^ ^
^ ^ ^
^ ^ ^
И поскольку вы запрашиваете более подробный пример кода:
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
После значений start
и end
:
[0:3) #[1,2,3]
[3:6) #[4,5,6]
[6:9) #[7,8,9]
FWIW, вы можете получить тот же результат с помощью map ()
с начальным аргументом None
:
>>> map(None,*[iter(s)]*3)
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
Подробнее о zip ()
и map ()
: http://muffinresearch.co.uk/archives/2007/10/16/python-transposing-lists-with-map-and-zip/
iter(s)
возвращает итератор для s.
[iter(s)]*n
делает список из n раз одного и того же итератора для s.
Таким образом, при выполнении zip(*[iter(s)]*n)
он извлекает элемент из всех трех итераторов из списка по порядку. Поскольку все итераторы являются одним и тем же объектом, он просто группирует список в куски по n
.