[ expression | for parameter in loop | optional condition ]
We are building a list that will be composed of the expressions evaluated from the loop against the conditional.
evens = [x for x in range(1, 100) if x % 2 == 0]
odd_cubes = [x ** 3 for x in range(1, 22) if x % 2]
Both examples are trivial and can be simplified but study them, anyway.
[x ** 3 for x in range(1, 22) if x % 2]
------ --------------------- --------
/ | \
expression for loop condition
Technically, a comprehension is itself an expression (anything that resolves to a value) so it contains no statements, only expressions. Note that all the expressions center around the parameter of the for loop.
The above example is imperative code made of statements. It can not be written as a return statement or passed into a function or string literal (f-string).
A comprehension is an expression which can be written in a return statement, can be passed to a function, and can be printed.
>>> def range10():
return [a for a in range(10)] # return from a function
>>> print (f"{range10()}")
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> def times2(s):
return [x * 2 for x in s]
>>> print (f"{times2(range10())}") # pass to a function
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> print (f"{[a for a in range(10)]}") # print in an f-string
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
Expressions are a crucial part of functional programming. This concept will surface more and more.
This might be a silly question, but does it matter where in the list comprehension we put the if/else statements?
In this first example, the if statement was placed at the end:
numbers = [2, -1, 79, 33, -45]
negative_doubled = [num * 2 for num in numbers if num < 0]
print(negative_doubled)
But in this other example, the if/else was placed in the middle:
numbers = [2, -1, 79, 33, -45]
doubled = [num * 2 if num < 0 else num * 3 for num in numbers ]
print(doubled)
Is there a preference as to where the if/else statements should go? Like if there is only an if statement, should it always be at the end and if there is an if/else statement, should it always be in the middle? Or does where we place an if statement or an if/else statement not really matter?
The if on the right hand side is part of the comprehension syntax, using it effectively filters out certain iterations from your loop
[5] == [x for x in range(10) if x == 5] # True
The left hand side is an expression that is not specific to list comprehensions at all, it’s often called a ternary expression but the Python docs call it a conditional expression. You can write conditional expressions in most place as an expression is accepted, so far as I’m aware-
x = 5
"blue" == "red" if x > 10 else "blue" # True
So whilst you can use it inside certain comprehensions it’s not limited to comprehensions and it does not have a filtering behaviour; it simply returns one of two expressions (like “red” or “blue” above).
A rather silly example (no filtering, just controls what expression evaluates to)-
example = [x if x != 5 else "bang" for x in range(10)]
print(example)
Out: [0, 1, 2, 3, 4, 'bang', 6, 7, 8, 9]
hey @mtf is it necessary to use list comprehension everytime in code cause i find easy writing loop without list comprehension. what are the benifits of using list comprehension?
Work with what is comfortable, and with what you know. Your workflow will expand over time. Some style guides actually recommend against expressions in favor of imperative constructs, for readability, but also for portability (as in port to another language).
One benefit of comprehensions is they are expressions that can be used as a return value, an argument, or within another expression, including string interpolation. We can even write a comprehension in a comprehension.
As expressions they are values, not constructs or statements. We cannot return a for or while loop, or write them inside an expression.