0

I am learning Python 3 and I saw that you can zip 2 lists together, like this:

l1 = [1,2,3]
l2 = ['a','b','c']

l3 = zip(l1,l2)
print(list(zip_L1L2))
# Output: [(1, 'a'), (2, 'b'), (3, 'c')]

And then reverse the process like that:

l4, l5 = zip(*l3)

but I cannot wrap my head around why it works...

Ailete619
  • 194
  • 1
  • 18

1 Answers1

0

Eureka!

While I was trying to write my question clearly, I stumbled upon this answer Why does x,y = zip(*zip(a,b)) work in Python?, which gave me a hint that I still did not get before trying it in a REPL. The key is unpacking the result of zip:

print(*zip(l1,l2))
# Output: (1, 'a') (2, 'b') (3, 'c')

We get 3 tuples of 2 elements, which are treated like 3 lists of 2 elements passed as arguments to zip:

l1 = [ 1 , 2 ]
l2 = ['a','b']
l3 = ['+','-']

print(list(zip(l1,l2,l3)))
# Output: [(1, 'a', '+'), (2, 'b', '-')]

※ Note that if you use 3 lists of 4 elements, zip will output 4 lists of 3 elements

l1 = [ 1 , 2 , 3 , 4 ]
l2 = ['a','b','c','d']
l3 = ['+','-','*','/']

print(list(zip(l1,l2,l3)))
# Output: [(1, 'a', '+'), (2, 'b', '-'), (3, 'c', '*'), (4, 'd', '/')]

matrix rotation

I now think of it as rotating values in a matrix 90° to make rows into columns and columns into rows.

It is like rotating a matrix by providing the rows as arguments instead of the matrix itself.

multiple variable assignment and tuple/list unpacking

The last piece of the puzzle is to unpack the result and assign each tuple in its own variable using multiple assignment!

l1 = [1,2,3]
l2 = ['a','b','c']
l3,l4= zip(*zip(l1,l2))

print('l3= ',l3)
print('l4= ', l4)
# Output: l3=  (1, 2, 3)
#         l4=  ('a', 'b', 'c')

Epilogue

I decided to keep writing this Q&A to learn by explaining what I had discovered by experimenting, after not immediately getting the meaning of the answer I found while writing.

I also hope that my analogy with matrix rotation will help someone else get it faster in the future.

Ailete619
  • 194
  • 1
  • 18
  • *"I now think of it as rotating values in a matrix 90° to make rows into columns and columns into rows."* This really over-complicates things. All `zip` is doing is iterating the provided iterables at the same time, one index at a time (and if they aren't of the same length, stopping when the shortest is exhausted) – DeepSpace Jun 09 '22 at 02:39
  • I think an analogy makes it easier to understand the concept by likening it to something more tangible while not 100% correct. Your explanation, while correct _(but incomplete: `zip` iterates and then does what?)_, does not answer my question and would not have helped me understand why and how `zip(*zip(...))` works ... – Ailete619 Jun 09 '22 at 05:07