Someone

blogged about Python not having an unzip function to go with zip().

unzip is straight-forward to calculate because:

>>> t1 = (0,1,2,3)

>>> t2 = (7,6,5,4)

>>> [t1,t2] == zip(*zip(t1,t2))

True

### Explanation

In answer to a commentator, I have written a (large), program to explain the above.

unzip_explained.py:

'''

Explanation of unzip expression zip(*zip(A,B))

References:

1: Unpacking argumment lists

http://www.network-theory.co.uk/docs/pytut/UnpackingArgumentLists.html

2: Zip

>>> 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.

'''

**def** show_args(*positional, **kwargs):

"Straight-forward function to show its arguments"

n = 0

**for** p **in** positional:

**print** " positional argument", n, "is", p

n += 1

**for** k,v **in** sorted(kwargs.items()):

**print** " keyword argument", k, "is", v

A = tuple( "A%i" % n **for** n **in** range(3) )

**print** "\n\nTuple A is:"; **print** " ", A

B = tuple( "B%i" % n **for** n **in** range(3) )

**print** "Tuple B is:"; **print** " ", B

**print** "\nLets go slowly through the expression: [A,B] == zip(*zip(A,B))\n"

**print** "List [A,B] is:"

**print** " ", [A,B]

**print** "zip(A,B) has arguments:"; show_args(A,B)

**print** "zip(A,B) returns:"

**print** " ", zip(A,B)

**print** "The leftmost zip in zip(*zip(A,B)), due"

**print** " to the 'list unpacking' of the previous"

**print** " value has arguments of:"; show_args(*zip(A,B))

**print** "The outer zip therefore returns:"

**print** " ", zip(*zip(A,B))

**print** "Which is the same as [A,B]\n"

And here is the program output:

Tuple A is:

('A0', 'A1', 'A2')

Tuple B is:

('B0', 'B1', 'B2')

Lets go slowly through the expression: [A,B] == zip(*zip(A,B))

List [A,B] is:

[('A0', 'A1', 'A2'), ('B0', 'B1', 'B2')]

zip(A,B) has arguments:

positional argument 0 is ('A0', 'A1', 'A2')

positional argument 1 is ('B0', 'B1', 'B2')

zip(A,B) returns:

[('A0', 'B0'), ('A1', 'B1'), ('A2', 'B2')]

The leftmost zip in zip(*zip(A,B)), due

to the 'list unpacking' of the previous

value has arguments of:

positional argument 0 is ('A0', 'B0')

positional argument 1 is ('A1', 'B1')

positional argument 2 is ('A2', 'B2')

The outer zip therefore returns:

[('A0', 'A1', 'A2'), ('B0', 'B1', 'B2')]

Which is the same as [A,B]