0

If i have two empty lists and i want to populate them with all "a"s and "b"s in the same object, can i do sometihng like:

a, b = [foo.a, foo.b for foo in foo]

Because currently I have them separated into two separate list comprehensions.

a = [foo.a for foo in foo]

b = [foo.b for foo in foo]

And so I was wondering if I can somehow consolidate them into one line and argument.

Armangh
  • 9
  • 2
  • Your list comprehension is creating a list of tuples, not two lists. – Barmar Aug 08 '22 at 20:00
  • True, also found someone else asking a similar thing https://stackoverflow.com/questions/10479319/possible-to-return-two-lists-from-a-list-comprehension and the comments say its not only a bad idea in aesthetics but its also slower than having two separate list comprehensions. No gain, just bad readability. – Armangh Aug 08 '22 at 20:15

3 Answers3

5

A list comprehension can only create one list. Your code is create a list of tuples (except that the tuple elements need to be in parentheses to prevent a syntax error).

You can unzip this into two lists, though:

a, b = zip(*[(foo.a, foo.b) for foo in foo])

See How to unzip a list of tuples into individual lists? for an explanation of this.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • God that's hard to read though. It's worse than having two different list comprehensions, and worse than having an explicit for loop doing two things.Technically, isn't the unzipping doing another (hidden) iteration anyway? – ScienceSnake Aug 08 '22 at 21:23
  • 1
    True, I don't actually recommend it. – Barmar Aug 08 '22 at 21:27
3

You can always make it one line with a comma. However making it one line, if anything, makes the code less readible.

a, b = [foo.a for foo in foo], [foo.b for foo in foo]
  • That's fair enough. I guess this is what i'm asking for but it wouldn't be as intuitive and doesn't benefit much. Thanks, i guess i'll stick to two list comprehensions – Armangh Aug 08 '22 at 20:09
0

You can do it with one loop, but it's not a comprehension

a, b = [], []

for foo in foos:
    a.append(foo.a)
    b.append(foo.b)

I changed your for foo in foo to for foo in foos, which is what I assumed you meant, otherwise the iteration makes very little sense.

ScienceSnake
  • 608
  • 4
  • 15