# Transpose/Unzip Function (inverse of zip)?

### Question

I have a list of 2-item tuples and I'd like to convert them to 2 lists where the first contains the first item in each tuple and the second list holds the second item.

For example:

``````original = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
# and I want to become...
result = (['a', 'b', 'c', 'd'], [1, 2, 3, 4])
``````

Is there a builtin function that does that?

1
465
3/27/2019 12:23:53 PM

`zip` is its own inverse! Provided you use the special * operator.

``````>>> zip(*[('a', 1), ('b', 2), ('c', 3), ('d', 4)])
[('a', 'b', 'c', 'd'), (1, 2, 3, 4)]
``````

The way this works is by calling `zip` with the arguments:

``````zip(('a', 1), ('b', 2), ('c', 3), ('d', 4))
``````

… except the arguments are passed to `zip` directly (after being converted to a tuple), so there's no need to worry about the number of arguments getting too big.

715
6/13/2017 12:09:24 AM

You could also do

``````result = ([ a for a,b in original ], [ b for a,b in original ])
``````

It should scale better. Especially if Python makes good on not expanding the list comprehensions unless needed.

(Incidentally, it makes a 2-tuple (pair) of lists, rather than a list of tuples, like `zip` does.)

If generators instead of actual lists are ok, this would do that:

``````result = (( a for a,b in original ), ( b for a,b in original ))
``````

The generators don't munch through the list until you ask for each element, but on the other hand, they do keep references to the original list.