269

I have a list that looks like this:

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

Semnodime
  • 1,872
  • 1
  • 15
  • 24
Breixo
  • 2,860
  • 2
  • 15
  • 9
  • 23
    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
  • 9
    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

519
>>> 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
  • 12,588
  • 14
  • 59
  • 110
agf
  • 171,228
  • 44
  • 289
  • 238
  • 7
    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
  • 35
    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
  • 2
    This is all fine and dandy until you get a `source_list` that has zero length. Then you will get an error instead of 2 empty lists like you would expect. – robot_rover Jun 06 '22 at 12:40
38
list1 = (x[0] for x in source_list)
list2 = (x[1] for x in source_list)
BiBi
  • 7,418
  • 5
  • 43
  • 69
S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 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
  • 7
    -1, the solution with zip() is more pythonic and doesn't have two for loops – naeg Sep 26 '11 at 17:42
  • 20
    @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
  • 2
    @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
  • 4
    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
  • @sachinruk zip is NOT faster. A loop with an append is not equivalent to a comprehension expression. The list comprehension version is faster. https://i.stack.imgur.com/cJVIX.png – RuRo Aug 27 '23 at 17:44