0

I'm trying to understand the need to unpack the arguments using * when the input to zip is a 2D list. The docs state,

[zip] Returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables.

So, regarding the second print statement below, I expected it to be just like the ones before and after it. I am having trouble connecting the description of zip to this result.

MWE:

x = [1, 2, 3]
y = [4, 5, 6]

print zip(x, y)
print zip([x, y])  # don't understand this result
print zip(*[x, y])

Result:

[(1, 4), (2, 5), (3, 6)]
[([1, 2, 3],), ([4, 5, 6],)]
[(1, 4), (2, 5), (3, 6)]
bcf
  • 2,104
  • 1
  • 24
  • 43
  • 2
    2nd print is equal to print zip([[1,2,3], [4,5,6]]). You're only passing one argument (a list of list) instead of 2 lists like the 1st and 3rd one – marcadian Sep 12 '16 at 16:51
  • @marcadian Thanks, this really cleared it up for me. – bcf Sep 12 '16 at 17:02

1 Answers1

5

Consider this example:

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> z = [7, 8, 9]
>>> zip(x,y,z)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> zip(x,y)
[(1, 4), (2, 5), (3, 6)]
>>> zip(x)
[(1,), (2,), (3,)]
>>> zip()
[]

Observe that zip with a single argument (and even with no arguments!) follows the same pattern. It always returns a sequence of tuples, where the tuples (if there are any) have the same number of members as the arguments to zip. Even when there's only one argument to zip.

Now consider the case you're asking about:

zip([x, y])

This is just zip with one argument! Zip isn't going to try to be clever and poke about inside the elements of the sequence you give it. It doesn't know or care that the elements of the sequence you gave it are themselves sequences. Zip is (thankfully!) simple and predictable. If you give it one argument it returns you a sequence of 1-tuples. In this case those 1-tuples contain a list each, but again, zip doesn't care! They could be strings or numbers or None or anything!

>>> zip([x, y])
[([1, 2, 3],), ([4, 5, 6],)]
>>> zip([x, 'marmalade'])
[([1, 2, 3],), ('marmalade',)]
>>> zip([None, y])
[(None,), ([4, 5, 6],)]
ForceBru
  • 43,482
  • 10
  • 63
  • 98
Weeble
  • 17,058
  • 3
  • 60
  • 75