zip(*[iter(s)]*n)은 Python에서 어떻게 작동합니까?
s = [1,2,3,4,5,6,7,8,9]
n = 3
list(zip(*[iter(s)]*n)) # returns [(1,2,3),(4,5,6),(7,8,9)]
안녕하십니까?zip(*[iter(s)]*n)일? 만약 그것이 더 장황한 코드로 쓰여진다면 어떻게 보일까요?
이는 목록을 동일한 크기의 청크로 분할하는 데 사용되는 기술입니다. 문제에 대한 일반적인 개요는 해당 질문을 참조하십시오.
iter() 시퀀스 위의 반복기입니다.[x] * n다음을 포함하는 목록을 생성합니다.n양의x즉, 길이표n각 요소가 있는 곳x.*arg함수 호출에 대한 인수로 시퀀스를 압축 해제합니다.따라서 동일한 반복기를 에 세 번 전달하고 매번 반복기에서 항목을 가져옵니다.
x = iter([1,2,3,4,5,6,7,8,9])
print(list(zip(x, x, x)))
다른 훌륭한 답변들과 논평들은 논쟁을 풀고 지퍼()의 역할을 잘 설명합니다.
이그나시오와 우주카첼이 말했듯이, 당신은 다음과 같이 지나갑니다.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/
제 생각에 모든 답(반복기에 익숙한 사람들에게는 분명하지만 다른 사람들에게는 그렇게 분명하지 않은 한 가지는 -입니다.
우리는 같은 반복기를 가지고 있기 때문에, 그것은 소비되고 나머지 요소들은 zip에 의해 사용됩니다.그래서 만약 우리가 그 목록을 사용하지 않고, 그 목록을 사용한다면요.
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)]
반복기를 사용하면 값을 팝업하고 사용 가능한 상태로 유지되므로 zip에 대해 0이 소비되면 1을 사용하고 2를 사용한 다음 2를 사용할 수 있습니다.아주 미묘한 것이지만, 꽤 영리합니다!!!
iter(s)s에 대한 반복기를 반환합니다.
[iter(s)]*n에 대해 동일한 반복기 n배의 목록을 만듭니다.
그래서 할 때는.zip(*[iter(s)]*n)목록에서 세 개의 반복자 모두에서 항목을 순서대로 추출합니다.모든 반복자가 동일한 개체이기 때문에 목록을 여러 개로 그룹화합니다.n.
이런 식으로 zip을 사용하는 것에 대한 조언 한 마디.목록의 길이가 균등하게 분할되지 않으면 목록이 잘립니다.이 문제를 해결하려면 채우기 값을 사용할 수 있는 경우 tools.izip_longest를 사용합니다.또는 다음과 같은 것을 사용할 수 있습니다.
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:], ]
용도:
for ints in n_split(range(1,12), 3):
print ', '.join([str(i) for i in ints])
인쇄:
1, 2, 3
4, 5, 6
7, 8, 9
10, 11
"똑똑함"의 층을 풀면 다음과 같은 동일한 철자를 더 쉽게 찾을 수 있습니다.
x = iter(s)
for a, b, c in zip(*([x] * n)):
print(a, b, c)
이는 결과적으로 훨씬 덜 중요한 것과 같습니다.
x = iter(accounts_iter)
for a, b, c in zip(x, x, x):
print(a, b, c)
이제 분명해지기 시작할 겁니다.입니다.x에서, 반에서복각,zip()에서, 리에비들화, 전밀들▁under라고 부릅니다.next(x)전달된 각 반복기 개체에 대해 세 번, 한 번씩.하지만 이것은 매번 같은 반복 개체입니다.그래서 처음 세 가지를 제공합니다.next(x)결과를 생성하고 공유 반복기 개체가 다음에 네 번째 결과를 전달할 때까지 대기합니다.거품을 내고, 헹구고, 반복합니다.
그나저나, 당신이 분석하고 있는 것 같습니다.*([iter(x)]*n)당신의 머리 속에 잘못 들어 있습니다.에 오는 행*n먼저 발생하고, 그 다음에 접두사가 발생합니다.* n에 됩니다.*n창조했다.f(*iterable)는 전를걸위바가로다니기입한화기다▁for를 호출하는 가기입니다.f()인수를 하여 각 에 대해 사용합니다.iterable배달합니다.
저는 작동 방식을 진정으로 내재화하기 위해 각 부분 단계를 분해해야 했습니다.REPL의 메모:
>>> # refresher on using list multiples to repeat item
>>> lst = list(range(15))
>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> # lst id value
>>> id(lst)
139755081359872
>>> [id(x) for x in [lst]*3]
[139755081359872, 139755081359872, 139755081359872]
# replacing lst with an iterator of lst
# It's the same iterator three times
>>> [id(x) for x in [iter(lst)]*3 ]
[139755085005296, 139755085005296, 139755085005296]
# without starred expression zip would only see single n-item list.
>>> print([iter(lst)]*3)
[<list_iterator object at 0x7f1b440837c0>, <list_iterator object at 0x7f1b440837c0>, <list_iterator object at 0x7f1b440837c0>]
# Must use starred expression to expand n arguments
>>> print(*[iter(lst)]*3)
<list_iterator object at 0x7f1b4418b1f0> <list_iterator object at 0x7f1b4418b1f0> <list_iterator object at 0x7f1b4418b1f0>
# by repeating the same iterator, n-times,
# each pass of zip will call the same iterator.__next__() n times
# this is equivalent to manually calling __next__() until complete
>>> iter_lst = iter(lst)
>>> ((iter_lst.__next__(), iter_lst.__next__(), iter_lst.__next__()))
(0, 1, 2)
>>> ((iter_lst.__next__(), iter_lst.__next__(), iter_lst.__next__()))
(3, 4, 5)
>>> ((iter_lst.__next__(), iter_lst.__next__(), iter_lst.__next__()))
(6, 7, 8)
>>> ((iter_lst.__next__(), iter_lst.__next__(), iter_lst.__next__()))
(9, 10, 11)
>>> ((iter_lst.__next__(), iter_lst.__next__(), iter_lst.__next__()))
(12, 13, 14)
>>> ((iter_lst.__next__(), iter_lst.__next__(), iter_lst.__next__()))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
# all together now!
# continuing with same iterator multiple times in list
>>> print(*[iter(lst)]*3)
<list_iterator object at 0x7f1b4418b1f0> <list_iterator object at 0x7f1b4418b1f0> <list_iterator object at 0x7f1b4418b1f0>
>>> zip(*[iter(lst)]*3)
<zip object at 0x7f1b43f14e00>
>>> list(zip(*[iter(lst)]*3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 14)]
# NOTE: must use list multiples. Explicit listing creates 3 unique iterators
>>> [iter(lst)]*3 == [iter(lst), iter(lst), iter(lst)]
False
>>> list(zip(*[[iter(lst), iter(lst), iter(lst)]))
[(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3), ....
아마도 파이썬 인터프리터에서 무슨 일이 일어나고 있는지 보는 것이 더 쉬울 것입니다.ipython와 함께n = 2:
In [35]: [iter("ABCDEFGH")]*2
Out[35]: [<iterator at 0x6be4128>, <iterator at 0x6be4128>]
그래서 우리는 같은 반복기 개체를 가리키는 두 반복기 목록을 가지고 있습니다.하세요.iter개체에서 반복기 개체를 반환하고 이 시나리오에서는 다음과 같은 반복기로 인해 두 번 반복됩니다.*2파이썬 통사적 설탕반복기도 한 번만 실행됩니다.
또한 임의의 수의 반복 가능성(시퀀스는 반복 가능)을 사용하고 각 입력 시퀀스의 i'번째 요소에서 튜플을 생성합니다.이 경우 두 반복기가 모두 동일하므로 zip은 출력의 각 2요소 튜플에 대해 동일한 반복기를 두 번 이동합니다.
In [41]: help(zip)
Help on built-in function zip in module __builtin__:
zip(...)
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]
Return a list of tuples, where each tuple contains the i-th element
from each of the argument sequences. The returned list is truncated
in length to the length of the shortest argument sequence.
언팩()* 조작자는 2요소 튜플을 생성하기에 충분한 입력이 없을 때까지 반복기가 소진되도록 보장합니다.
은 이 값 다 음 있 수 니 습 다 확 할 장 로 은 값 으 ▁value ▁of 다 ▁any ▁to ▁be ▁this 니 있 ▁extended ▁can 습 이 수 값n그리고.zip(*[iter(s)]*n)설명된 대로 작동합니다.
x = [1,2,3,4,5,6,7,8,9]
zip(*[iter(x)] * 3)
다음과 같습니다.
x = [1,2,3,4,5,6,7,8,9]
iter_var = iter(x)
zip(iter_var,iter_var,iter_var)
ㅠㅠzip() 값을가다니에서 다음 .iter_var 값로으이동다니합▁of▁value▁next다니의 다음 값으로 이동합니다.x달기보를 실행해 .next(iter_var)어떻게 작동하는지 확인할 수 있습니다.
언급URL : https://stackoverflow.com/questions/2233204/how-does-zipitersn-work-in-python
'programing' 카테고리의 다른 글
| MySQL보다 Oracle을 선택해야 하는 경우 (0) | 2023.07.26 |
|---|---|
| MariaDB 인덱스 비교 (0) | 2023.07.26 |
| Angular 빌드 프로세스를 가속화하는 방법 (0) | 2023.07.26 |
| parseInt vs sunaryplus, 어떤 것을 사용해야 합니까? (0) | 2023.07.26 |
| 각도 2 - 라우팅 - 관찰 가능한 작업을 활성화할 수 있음 (0) | 2023.07.26 |