Alex Rivera | Logout

Transpose/Unzip Function (inverse of zip)?

Asked 2008-08-21T04:29:07.580
616

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?


See also: Transpose list of lists if the specific choice of lists vs. tuples in the result matters. Most answers here assume it doesn't.

Edit
Report

1 Answer

920

In 2.x, 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)]

This is equivalent to calling zip with each element of the list as a separate argument:

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.

In 3.x, zip returns a lazy iterator, but this is trivially converted:

>>> list(zip(*[('a', 1), ('b', 2), ('c', 3), ('d', 4)]))
[('a', 'b', 'c', 'd'), (1, 2, 3, 4)]
answered 2008-08-21T04:36:29.590

Your Answer