Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python list comprehension with multiple 'if's

We all know python's

[f(x) for x in y if g(x)] 

syntax.

However the AST representation of list comprehension has room for more than one 'if' expression:

comprehension = (expr target, expr iter, expr* ifs) 

Can somebody give me an example of python code that would produce an AST with more than one 'if' expression?

like image 879
Stefan Avatar asked Mar 06 '13 13:03

Stefan


2 Answers

Just stack them after one another:

[i for i in range(100) if i > 10 if i < 50] 

Produces the integers between 11 and 49, inclusive.

like image 133
Emil Vikström Avatar answered Oct 17 '22 08:10

Emil Vikström


The grammar allows for multiple if statements because you can mix them between the for loops:

[j for i in range(100) if i > 10 for j in range(i) if j < 20] 

The comprehension components should be viewed as nested statements, the above translates to:

lst = [] for i in range(100):     if i > 10:         for j in range(i):             if j < 20:                 lst.append(j) 

This also means that you can use multiple if statements without for loops in between:

[i for i in range(100) if i > 10 if i < 20] 

Although non-sensical (just combine those using and or with chained operators), it does translate to a legal nested set of statements still:

lst = [] for i in range(100):     if i > 10:         if i < 20:             lst.append(i) 

The grammar and parser do not specifically disallow such usage, in the same way that Python doesn't disallow you to nest if statements.

Note that PEP 202 – List Comprehensions (the original proposal document that added this feature to the language) actually includes a double-if comprehension in the examples section:

>>> print [(i, f) for i in nums for f in fruit if f[0] == "P" if i%2 == 1] [(1, 'Peaches'), (1, 'Pears'), (3, 'Peaches'), (3, 'Pears')] 
like image 41
Martijn Pieters Avatar answered Oct 17 '22 10:10

Martijn Pieters