1

I am trying to call a function for a range of values. That function returns a list. The goal is to combine all the returned lists into a list.

Here is a test function that returns a list:

def f(i):
    return [chr(ord('a') + i), chr(ord('b') + i), chr(ord('c') + i)]

Here is a list comprehension that does what I need that I came up with after some experimentation and a lot of StackOverflow reading:

y = [a for x in (f(i) for i in range(5)) for a in x]

However, I do not understand why and how it works when a simple loop that solves this problem looks like this:

y = []
for x in (f(i) for i in range(5)):
    for a in x:
        y.append(a)

Can someone explain?

Thanks!

4
  • 11
    What exactly is your question? Are you asking why the last two implementations produce equivalent outputs? Commented Oct 1, 2019 at 19:08
  • @CoryKramer, I don't understand how to read it and how to map it to the loop-based implementation. Commented Oct 1, 2019 at 19:12
  • 1
    But it's literally the same as the first two lines of the for loop. As in, the same words in the same order. What's your confusion? Commented Oct 1, 2019 at 19:16
  • @DanielRoseman, if I take the comprehension apart, it does not exactly map to the for loop. For example, (f(i) for i in range(5)) returns a list of lists. x becomes a single list in that list of lists. What does a for x achieve in this case and how that a is related to for a in x it the end of the expression? Commented Oct 1, 2019 at 19:19

3 Answers 3

2

This may be a better illustration, following Bendik Knapstad's answer:

[
    a # element added to the list
    for x in (f(i) for i in range(5)) # outer loop
        for a in x # inner loop that assigns to element to be added to the list
]
Sign up to request clarification or add additional context in comments.

Comments

1

Answering to this:

However, I do not understand why and how it works (list comprehensions) when a simple loop that solves this problem looks like this (for loops)

Yes, they both can work but there are some differences. First, with list comprehensions, you are able to generate a list (because that's the output) after assigning it to a variable. Whereas in a for loop you must have the list created (regardless if it's empty or not) if you wish to use append later on perform any updating/deleting/re-indexing operation.

Second, simplicity. While for loops might be used in complex tasks where you need to apply a wide variety of functions, and maybe use RNGs, list comprehensions are always preferrable when it comes to dealing with lists and performing rather 'basic' operations (of course you can start nesting them and turn them into something more complex).

Third and finally, speed. List comprehensions tend to perform baster when compared to for loops for simple tasks.

More in-depth information regarding listcomp and for loops can be read in python's official tutorial. https://docs.python.org/3/tutorial/datastructures.html

Comments

0

Nested list comprehensions are hard to read. But if you look at the two expressions you'll se that they contain the same logic. In the list comprehension the first a is the part you want to keep in the list. It's equal to the y.append(a) in the for loop. The for x in (f(i) for i in range(5)) is the same as in your for loop The same goes for the next line for a in x So for x in (f(i) for i in range(5)) creates a list x So if we had the list x already we could write y= [a for a in x]

1 Comment

Thank you. This now makes sense. The first a is what is being added to the list. And both for loops remain in the same order as they would've been in a regular conditional statement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.