FAQ: Learn Python: Loops - List Comprehensions

Another cool aspect of comprehensions just hit me… Point of reference. Any polling does not involve tracking down a list or dictionary, we’re inside the thing. Everything is directly exposed at this level, albeit not accessible. The only thing allowed to happen is growing of the list or dictionary. Since this operation is so definitive, freeing up the polling process of having to find the list every time just makes sense.

Bottom line, style guides, my opinions, &c. aside, make constructive and well thought out use of comprehensions. Should you enter the study of functional programming in Python there is no proviso against their use.

A bit of this, and a bit of that. What we sprinkle, and where it lands, well, that’s the thing we wait for. Every scenario has its own constraints. Best not to mix writing styles without relatable wherewithal. Expressive vs. imperative. Two sides of the same coin, but with remarkably different code patterns. Pick a side to explore, explore it, then pick the other side and explore it. That’s how you get a feel for this stuff. Keep an open mind and never stop exploring.

1 Like

This was an interesting read, as I had the same question: Python: For Loop vs. List Comprehension | by Sebastian Witowski | Python in Plain English

2 Likes

Why does this work [height for height in heights if height > 161] but this throw an error [height if height > 161 for height in heights]?

The second example is missing the else clause before the for. If it is not needed, then move the if to the other end, as is shown in the example that works.

It is a nuance of the syntax that may be better explained in the documentation but it also stems from the fact that Python supports else on for loops so an else clause after the for loop would not be interpreted as belonging to the if. Therefore, when it is used, it needs to be ahead of the for loop.

Got it. Thanks for the reply.

1 Like

Does the order in which you write the statements matter? For example:

heights = [161, 164, 156, 144, 158, 170, 163, 163, 157]
can_ride_coaster = [height for height in heights if height > 161]
print(can_ride_coaster)

This code is the correct way to write it, as it prints out the correct answer codecademy was looking for, but I don’t believe that there was any mention of an order of operations for List Comprehension. I tried putting the if statement at the beginning, like so:

heights = [161, 164, 156, 144, 158, 170, 163, 163, 157]
can_ride_coaster = [height if height > 161 for height in heights]
print(can_ride_coaster)

but I ended up getting a syntax error. But as I was looking over my notes, some previous examples that were given did this same thing, but without an error. Does anyone have any idea why that is?

Check to see if the previous examples you mentioned included an else clause, which is required when the if is written in front of the for.

[x if x > 0 else 0 for x in interable]
             /
         required

[x for x in iterable if x > 0]

The latter example cannot have an else after the if.

1 Like

Thank you MTF for your answer. I was struggling to understand the same question that adigio1998 had … and your answer cleared things up for me!

1 Like

Can we use elif in a List Comprehensions?

As I understand it, we cannot since it implies another statement, not expression. We can use a conditional expression, though. The ‘if’ and the ‘else’ need to trace to expressions, not statements.

>>> a = [-1, 2, 3, -4, 5, -6, -7, 8, 9]
#        |...............conditional expression.............|
>>> b = [x if x < 0 else x * 2 if x & 1 else 'positive even' for x in a]
#        \       \         \        \              \
#         \   condition     \      state            \
#      expression        expression              expression
>>> b
[-1, 'positive even', 6, -4, 10, -6, -7, 'positive even', 18]
>>> 
1 Like

the syntax related to if, and if else, is confusing, and could get annoying

I have found many instances where you receive a syntax error and then it goes away after you reload and run the program again. Not sure why this happens but it frustrates me to no end.

#List the elements > 161

heights = [161, 164, 156, 144, 158, 170, 163, 163, 157]

Why does the below syntax output boolean values?
can_ride_coaster = [num > 161 for num in heights]

…Versus the correct version: can_ride_coaster = [num for num in heights if num > 161]

the basic syntax for a list comprehension is:
new_list = [expression for item in iterable (condition)]

Your first example has the result of the expression “number > 161” first (which results in a Boolean value), regardless of the items in the current list (iterable). So, it’s saying, “is the number is greater than 161…looking at each number in this list” which will result in a boolean value.

as opposed to, 'item for item in this list if the number is > 161".

The conditional logic goes at the end of the expression in a list comprehension.

2 Likes

In the above instance this would be the case. There can also be a conditional for the expression, as well:

[x if x < 200 else 0 for x in iterable if x > 161]

The example may not make complete sense except to illustrate the two conditional positions. Note that the expression conditional MUST have an ELSE clause.

1 Like

Hi good people! I need a help!

On the List Comprehensions: conditionals exercise where we need to create a new list called can_ride_coaster that has every element from heights that is greater than 161 .

where:
heights = [161, 164, 156, 144, 158, 170, 163, 163, 157]

I wrote the following script, which produces the correct result [164, 170, 163, 163]. However, shouldn’t this script print every single number still? If I interpret the script, the condition states that any number higher than 161 should be multiplied by 1, and the rest should be left as-is? in other words, shouldn’t the script produces the exact same as the original list?

can_ride_coaster = [num * 1 for num in heights if num > 161]

print(can_ride_coaster)

I understand from the hint that the recommended script is:

can_ride_coaster = [elem for elem in heights if elem > 161]

but i’m still curious with the output of the first script that i wrote.

Any help is highly appreciated! Many thanks!

I don’t think multiplying by 1 factors into the instructions at all. If memory serves, the results of the list comprehension should be a list of boolean values, right? You’re writing the list comprehension to determine if peoples’ heights are tall enough to ride the roller coaster…so it’s either True or False.

Do you have a link to this? The original links above don’t redirect to the correct points in the lessons any longer.

visitor_heights = [161, 164, 156, 144, 158, 170, 163, 163, 157] can_ride_coaster = [height for height in visitor_heights if height > 161] print(can_ride_coaster)

i think this might be a slightly better way of introducing “Comprehension List” as it
would be easier to see the different parts. I am learning python at the moment and just staring at the
code with “heights” repeatedly got very confusing and made it harder to break down the parts of the code.