233

Possible Duplicate:
A Transpose/Unzip Function in Python

I have a list that looks like this:

list = (('1','a'),('2','b'),('3','c'),('4','d'))

I want to separate the list in 2 lists.

list1 = ('1','2','3','4')
list2 = ('a','b','c','d')

I can do it for example with:

list1 = []
list2 = []
for i in list:
   list1.append(i[0])
   list2.append(i[1])

But I want to know if there is a more elegant solution.

Community
  • 1
  • 1
Breixo
  • 2,500
  • 2
  • 13
  • 9
  • 19
    Please do not use built-in type names for variables. Don't call it `list`. Once you've created a variable `list`, you start to have weird things happen because the built-in function `list()` is now hidden by your variable. – S.Lott Sep 26 '11 at 17:36
  • 6
    That's a tuple, not a list. It's important to keep them straight in Python, even though they can be used similarly. – Russell Borogove Sep 26 '11 at 18:19

2 Answers2

442
>>> source_list = [('1','a'),('2','b'),('3','c'),('4','d')]
>>> list1, list2 = zip(*source_list)
>>> list1
('1', '2', '3', '4')
>>> list2
('a', 'b', 'c', 'd')

Edit: Note that zip(*iterable) is its own inverse:

>>> list(source_list) == zip(*zip(*source_list))
True

When unpacking into two lists, this becomes:

>>> list1, list2 = zip(*source_list)
>>> list(source_list) == zip(list1, list2)
True

Addition suggested by rocksportrocker.

Tommy
  • 11,318
  • 11
  • 58
  • 94
agf
  • 160,324
  • 40
  • 275
  • 231
  • 6
    To the OP, http://stackoverflow.com/questions/5239856/foggy-on-asterisk-in-python is helpful if you don't know about the "splat" operator. – dicato Sep 26 '11 at 18:07
  • 28
    I want to point out that the results of `zip(*list_of_pairs)` is not a pair of `list` but `tuple`. The difference can be important in some cases (e.g. append to it). So the `list1` and `list2` in the example should really be `tuple1` and `tuple2`. – Causality Feb 29 '16 at 20:40
  • @Causality Definitely true. I used the same names used in the question, where they are also `tuple`s. The mistake was pointed out in a comment on the question back when this was originally posted: http://stackoverflow.com/questions/7558908/unpacking-a-list-tuple-of-pairs-into-two-lists-tuples/7558990?noredirect=1#comment9163175_7558908 – agf Feb 29 '16 at 21:19
  • @agf, you're right. I missed that comment. – Causality Mar 01 '16 at 01:31
  • 1
    This is just awesome! **zip is its own reverse.** – bytestorm Oct 05 '19 at 18:27
32
list1 = (x[0] for x in source_list)
list2 = (x[1] for x in source_list)
BiBi
  • 6,378
  • 4
  • 38
  • 62
S.Lott
  • 373,146
  • 78
  • 498
  • 766
  • 4
    If you need actual `list`s you can index, you should use square brackets `[]` instead of parenthesis to make them list comprehensions instead of generator expressions. – agf Sep 26 '11 at 17:42
  • 5
    -1, the solution with zip() is more pythonic and doesn't have two for loops – naeg Sep 26 '11 at 17:42
  • 17
    @naeg, this is a perfectly correct, pythonic expression. You could even argue for the less trained programmer this is a better solution than to use the quite foggy `zip(*...)` syntax. – KillianDS Sep 26 '11 at 18:52
  • 1
    @KillianDS: Well, I don't consider the zip() function nor the unpacking of arguments as complex or foggy? Since the zip-answer has more upvotes, I guess others think the same. – naeg Sep 26 '11 at 19:44
  • 3
    It depends on the length of the tuples in the original list. If it is unknown or beyond 2, zip(* ) is better, otherwise, the solution here is nice too. – Causality Dec 14 '12 at 21:06
  • For anyone wondering, zip is faster: https://i.stack.imgur.com/ufedP.png – sachinruk Mar 15 '22 at 05:56