# How to understand n-length groups idiom zip(*[iter(s)]*n)

Hi forum,

I have trouble understanding this n-length groups idiom

``````>>> s = [1, 2, 3, 4, 5, 6]
>>> list( zip( *[ iter( s ) ] *2 ) )
[(1, 2), (3, 4), (5, 6)]
>>>
``````

Could you please teach me. Thanks in advance.

Does the whole expression evaluate in this order?

Step 1: iter(s)
It’s a iterator on a sequence.

Step 2: [ iter(s) ] *2
It’s a list repetition. Two iterators on the sequence. Take two value from the sequence one time. There’re two stream of iterator:
s1: [1, 3, 5]
s2: [2, 4, 6]

Step 3: *[ iter(s) ] *2
I do not understand the first * star operator. Is it unzip or unpack operator? Or are unzip and unpack the same thing? What does it do here?

Step 4: zip( *[ iter(s) ] *2)
s1: [1, 3, 5]
s2: [2, 4, 6]

So it’s equal to:
zip(s1, s2)

(1, 2), (3, 4), (5, 6)

Step 5: list( zip( * [ iter(s) ] *2 ) )
Constructs a list to show the zip result
[(1, 2), (3, 4), (5, 6)]

I wouldn’t phrase it that way. iter(s) returns an iterator object. [iter(s) *2] creates a list with that object duplicated. It’s not that there’s 2 streams, there’s just one object. The sequence that comes from that object depends on how it’s read.

``````>>> [iter(s)] *2
[<list_iterator object at 0x1059d36a0>, <list_iterator object at 0x1059d36a0>]
``````

One list with a duplicated object in the first two positions.

Then the first star unpacks the object.
`zip([....])` passes a list to zip as the only argument
`zip(*[....])` passes each element of the list to zip as separate arguments. So

`zip(*[iter(s)] * 2)` is equivalent to:
`i = iter(s) ; zip(i, i)`

1 Like

Is it in the form of a nested list:
[ [1,3,5], [2,4,6] ]

Thanks!

No, the iterator object inside isn’t examined until later. It’s a list with two object in it. Identical to what I showed earlier:

``````>>> [iter(s)] *2
[<list_iterator object at 0x1059d36a0>, <list_iterator object at 0x1059d36a0>]
``````

Semantically, you can think of it similar to nested lists (and zip() would behave the same way as if you did pass in nested lists)

1 Like

The critical thing about the iterator is that since it’s the same iterator, it’ll only produce the value once. So each iteration, `zip()` calls `next()` on it twice, giving two objects.

1 Like