how to separate a list into two lists?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Aug 7 02:27:24 CEST 2011

```Chris Angelico wrote:

> On Sat, Aug 6, 2011 at 6:07 PM, smith jack <thinke365 at gmail.com> wrote:
>> if a list L is composed with tuple consists of two elements, that is
>> L = [(a1, b1), (a2, b2) ... (an, bn)]
>>
>> is there any simple way to divide this list into two separate lists ,
>> such that L1 = [a1, a2... an]
>> L2=[b1,b2 ... bn]
>>
>> i do not want to use loop, any methods to make this done?
>
> One easy way is to use list comprehensions. Technically that'll
> involve a loop, but the loop is handled efficiently under the hood.
>
> L1 = [x[0] for x in L]
> L2 = [x[1] for x in L]

I hardly think that's "under the hood". It's right there: for x in L. How
much more explicitly a loop do you want?

To the original poster, Jack: if you don't loop over the list, how do you
expect to operate on each and every item?

Whether you write:

L1, L2 = [], []
for a,b in L:
L1.append(a)
L2.append(b)

or

L1, L2 = zip(*L)

or

L1 = [x[0] for x in L]
L2 = [x[1] for x in L]

you are still looping over the list. In the second case, the one-liner using
zip, you loop *twice*: once to unpack L into separate arguments, the second
time to zip them up. And the result you end up with are tuples, not lists,
so if you need lists, you have to loop *again*, over each tuple, converting
them to lists. Here's one way to do that while keeping it a one-liner:

L1, L2 = map(list, zip(*L))

If L is small, it really doesn't matter what you do, they will all be more
or less as efficient. Write whatever you feel looks best.

But if L is huge, then the difference between a four-liner that iterates
over the list once, and one-liner that iterates over it four times, may be
considerable.

--
Steven

```