Why does Python have two ways to filter a comprehension?

& (verbiage overflow)Fri 06 May 2016RSS

“Filtering” means placing a restriction on the elements to be added to a list returned by Python’s comprehension structure or the widely implemented map function. In Python it normally looks like this:

You can map a range of integers to a list:

>>> [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

And you can filter it, so to include only odd numbers, by placing an if-clause after the for clause:

>>> [i for i in range(10) if i % 2]
[1, 3, 5, 7, 9]

But if you use the fuller if-then syntax to filter or supplement the mapping process — say, to include 0 if an element is not odd — you place it before the for clause:

>>> [i if i % 2 else 0 for i in range(10)]
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9]

Why does Python have two different syntaxes for filtering in a comprehension, one before the for clause and one after?

Answer: It doesn’t. There are two different things happening here.

Only the first example is genuine filtering, which modifies the for clause with an if clause.

The second example is a two-way decision expression, an in-line if-else statement determining the assignment of i at the far left of the comprehension.

Keyword else never occurs in genuine filtering, while it is required in a two-way decision expression. It's coincidental that these two structures both seem to be serving the same function — in reality, they are serving different functions.

[end]

Comments are enabled.