Welcome, guest | Sign In | My Account | Store | Cart

Inverse of zip

Python, 13 lines
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13``` ```def unzip(args): """ inverse of zip. Given: ((1,"a"),(2,"b")) --> ((1,2),("a","b")) seq == unzip(zip(seq)) if seq is a rectangular matrix (all of its row has the same length. """ result = [] n = min(map(len,args)) for i in range(n):result.append([]) for i in range(len(args)): for j in range(n): result[j].append(args[i][j]) return tuple(result) ``` Christophe Delord 19 years, 3 months ago

unzip. A shorter version of unzip can be:

``````unzip = lambda l:tuple(zip(*l))
``````

or for older Python versions:

``````unzip = lambda l:tuple(apply(zip,l))
`````` Peter Scott 18 years, 7 months ago

Why isn't this standard? This is very useful; I don't see why it isn't in the python standard library. When I'm doing heavy list manipulations this is extremely handy.

PEP anyone? Sudhir Kumar 18 years, 6 months ago

isn't zip its own inverse? >>> zip((1, 2), ('a', 'b'))

[(1, 'a'), (2, 'b')]

``````>>> zip((1,"a"),(2,"b"))
``````

[(1, 2), ('a', 'b')]

Why do we need an unzip?

Thanks,

-- sudhir Denis Kaznadzey 18 years, 6 months ago

Simple unzip. unzip = lambda ll: apply (zip, ll)

such unzip is actually a matrix transposer;

also unzip (unzip (ll)) == ll Michael Hartl 17 years, 9 months ago

Another unzip. def unzip(seq): return zip(*seq) Michael Hartl 17 years, 9 months ago

Zip is not its own inverse. Zip isn't its own inverse in general, e.g.,

``````>>> zip(zip((1, 2, 3), (4, 5, 6), (7, 8, 9)))
[((1, 4, 7),), ((2, 5, 8),), ((3, 6, 9),)]
`````` Michael Hartl 17 years, 9 months ago

Redundancy. I just realized that this is equivalent to the first lambda expression on the top. Oh, well. It's redundant, but to my eye it looks more Pythonic. Frank P Mora 16 years, 6 months ago

Feed zip arguments correctly.

``````Zip *is* its own inverse.

You are giving your outer zip call a single argument. The inner zip
produces a single list of tuples. If you give zip a single argument
it will return what you are getting. If you precede any single list
with an asterisk in any function the function is passed len(list)
arguments.

Try this:

>>> zip( *zip( (1, 2, 3), (4, 5, 6), (7, 8, 9) ) )
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]

Kumar was manually separating the elements of his list. He was feeding
his second zip two arguments. He could have typed

>>> zip_out= zip((1, 2), ('a', 'b'))
>>> zip( *zip_out )
[(1, 2), ('a', 'b')]

and saved typing so he could focus on gaining more valuable insights.

The asterisk is necessary when using list compressions with zip.

>>> zip( *[ s.split() for s in (a b c d e f g, t u v w x y z) ] )
[('a', 't'), ('b', 'u'), ('c', 'v'), ('d', 'w'), ('e', 'x'), ('f', 'y'), ('g', 'z')]

Dictionaries are easily created in this fashion.

>>> dict( zip( *[ s.split() for s in (Q1 Q2 Q3 Q4, Jan Apr Jul Oct) ] ) )
{'Q1': 'Jan', 'Q3': 'Jul', 'Q2': 'Apr', 'Q4': 'Oct'}
`````` Created by Andres Tuells on Tue, 18 Dec 2001 (PSF)

### Required Modules

• (none specified)