What are the parts of list comprehension?

Question

What are the parts of list comprehension?

Answer

List comprehension can be intimidating at first! So let’s break it down into its three basic parts:

  1. The part we want to calculate: [x … …]
  2. The range of values we want to operate in: [... for x in range(start, end) …]
  3. The condition, if any, that must be met: [... … if x == some_condition]
    This is the example given: doubles_by_3 = [x * 2 for x in range(1, 6) if (x * 2) % 3 == 0]
    The part being calculated is x * 2.
    The range to operate in is for x in range(1, 6).
    The condition that each x must meet to be used is if (x * 2) % 3 == 0.
4 Likes

List comprehensions can use nested loops which when combined with a test function can be very powerful. The following example uses a function to test if the product of two numbers is a palindrome.

Eg.

11 * 11 == 121

111 * 111 == 12321

Here is our test function…

def is_palindrome_product(a, b):
    return str(a * b) == str(a * b)[::-1]

The following looks at only 3 digit numbers…

r = range(100, 1000)
p = [(m, n, m * n) for m in r for n in r if is_palindrome_product(m, n)]
print (len(p))    # 2470
print (p[-1])     # (995, 583, 580085)
9 Likes

You my friend are way ahead of me. :slight_smile:

4 Likes

What is the syntax of list comprehension? Does the order matter?

Eg:
even_squares =[x ** 2 for x in range(1,11) if x % 2 == 0]
Could I type those same operations in a different order and have it create the identical list?

2 Likes

list comprehension

    [(assignment expression) (for loop) (conditional)]

As we can deduce from this the order does matter.

x ** 2                  =>  assignment expression

for x in range(1, 11)   =>  for loop

if x % 2 == 0           =>  conditional
7 Likes

Got it. Thanks mtf :smile:

3 Likes

what about the example code as below,if…else With List Comprehension?
the for loop clause goes after the conditional clause?

obj = ["Even" if i%2==0 else "Odd" for i in range(10)]

Also , when i rearranged the order of the code above like this (shown as below ),moving for clause to the middle position ,then it failed when i run it .

obj = ["Even"for i in range(10) if i%2==0 else "Odd"]
SyntaxError: invalid syntax
2 Likes
>>> ['float' for x in range(10) if x % 1 else 'int']    # else is highlighted
SyntaxError: invalid syntax
>>> 

else must be before for else it might be construed as an else on the for and not the if.

>>> ['float' if x % 1 else 'int' for x in range(10)]
['int', 'int', 'int', 'int', 'int', 'int', 'int', 'int', 'int', 'int']
>>> ['float' if (x + x % 2 / 10) % 1 else 'int' for x in range(10)]
['int', 'float', 'int', 'float', 'int', 'float', 'int', 'float', 'int', 'float']
>>> 
5 Likes

Thx for explanation !!!

so in conclusion, can i said that as long as there is else clause , it must be put in the middle of the list comprehension ,whatever how many else are there ?

3 Likes

In general terms, when if is before the for it must be given an else clause; and, when it is after the for it cannot have an else.

4 Likes

how is execution order?

“doubles_by_3 = [x * 2 for x in range(1, 6) if (x * 2) % 3”

why in the “if” I have repeat “x*2”?

thnaks

2 Likes

Missing closing bracket on comprehension.

 [ ( expression to include in the list) (iterator) (conditional) ]

The expression is x * 2.

The iterator is for x in range(1, 6).

The conditional is, if x * 2 % 3.

The finished list will be,

[ 2, 4, 8, 10 ]

If you want the value x * 2 to be divisible by 3 then the condtional should be,

 if x * 2 % 3 == 0

which will generate,

[6]

The expression x * 2 is not so much repeated as part of the overall statement. We want x doubled if double x is divisible by three.

3 Likes

I know this is an old thread but…I think you’re missing what santyago is asking because I had the same question when going through the exercise and landed here. I figured it out using different syntax without using x ** 2 twice. Some of the replies in this thread seem to be misleading.

The key is that whether you would use x ** 2 twice or not seems to depend on what you’re trying to achieve with the code. What the code is actually doing that you aren’t ‘seeing’ is important.

These three different versions of the code produce two different results:

even_squares = [x for x in range(1, 11) if (x ** 2) % 2 == 0]
even_squares_02 = [x ** 2 for x in range(1, 11) if x % 2 == 0]
even_squares_03 = [x ** 2 for x in range(1, 11) if (x ** 2) % 2 == 0]

print even_squares
print even_squares_02
print even_squares_03

Results:
[2, 4, 6, 8, 10]
[4, 16, 36, 64, 100]
[4, 16, 36, 64, 100]

Without too much coding jargon it seems like this is happening:

  1. You are creating a variable that is a list.

  2. Establishing what you will do to each item in the list BUT this is happening outside of any logical test. this is what is referred to as the ‘expression’.

  3. Then you are CREATING the original list by initiating a FOR statement.

  4. Establishing that each variable in the original list will come from a RANGE of numbers, 1-11. Producing the numbers: 2,4,6,8,10 as the original list.

  5. Performing a logical test on the original list established by the RANGE

What you are printing with the different versions is either the original list, done by: using only one x ** 2 as part of the logical test and leaving only x in the “expression” part which leaves the list unmodified .

Or: printing/representing the results of the logical test by including that first x ** 2 prior to the FOR statement. By including it, you are essentially changing the list outside of any logical test to represent what the logical test is actually checking.

It’s interesting because it’s truly a question of whether you as the coder are interested in the numbers that produced the squares or the results of squaring the numbers. In other words: If 2 squared is 4: do I care about the 4 or the 2?

This post has no context since we do not know which lesson it is referring to. Please post a link to the exercise.

I would like to know if 'if x % 2 ’ equivalent to ‘if x % 2 == 0’ . Many thanks for an explanation about that.

They are the exact opposite. The first will be true when x % 2 is NOT zero.

1 Like

Thanks @mtf, Yeah, you are right.

1 Like