programing

zip(*[iter(s)]*n)은 Python에서 어떻게 작동합니까?

telebox 2023. 7. 26. 21:49
반응형

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

반응형