Coder Perfect

Pythonic way to combine FOR loop and IF statement


I know how to use both for loops and if statements on separate lines, such as:

>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
...     if x in a:
...         print(x)

And I know I can combine these using a list comprehension when the statements are simple, such as:

print([x for x in xyz if x in a])

But I can’t seem to locate a good example (to copy and learn from) illustrating a complex sequence of instructions (not just “print x”) that occur after a for loop and a few if statements are combined. Something along these lines, for example:

for x in xyz if x not in a:

Isn’t this how python is intended to function?

Asked by ChewyChunks

Solution #1

Generator expressions can be used in the following way:

gen = (x for x in xyz if x not in a)

for x in gen:

Answered by Kugel

Solution #2

According to The Zen of Python (which you should consult if you’re unsure whether your code is “Pythonic”):

Getting the sorted intersection of two sets in Python is as follows:

>>> sorted(set(a).intersection(xyz))
[0, 4, 6, 7, 9]

Or those xyz elements that aren’t in a:

>>> sorted(set(xyz).difference(a))
[12, 242]

You could flatten the loop by iterating over a well-named generator expression and/or executing a well-named function. It is rarely “Pythonic” to try to fit everything on one line.

I’m not sure what you’re attempting to accomplish with enumerate, but if it’s a dictionary, you should probably utilize the keys, like in:

>>> a = {
...     2: 'Turtle Doves',
...     3: 'French Hens',
...     4: 'Colly Birds',
...     5: 'Gold Rings',
...     6: 'Geese-a-Laying',
...     7: 'Swans-a-Swimming',
...     8: 'Maids-a-Milking',
...     9: 'Ladies Dancing',
...     0: 'Camel Books',
... }
>>> xyz = [0, 12, 4, 6, 242, 7, 9]
>>> known_things = sorted(set(a.iterkeys()).intersection(xyz))
>>> unknown_things = sorted(set(xyz).difference(a.iterkeys()))
>>> for thing in known_things:
...     print 'I know about', a[thing]
I know about Camel Books
I know about Colly Birds
I know about Geese-a-Laying
I know about Swans-a-Swimming
I know about Ladies Dancing
>>> print '...but...'
>>> for thing in unknown_things:
...     print "I don't know what happened on the {0}th day of Christmas".format(thing)
I don't know what happened on the 12th day of Christmas
I don't know what happened on the 242th day of Christmas

Answered by Johnsyweb

Solution #3

The following is a condensed version of the accepted answer:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]

for x in (x for x in xyz if x not in a):


It’s worth noting that the generator was left in place. This was tested with Python 2.7 and Python 3.6 (note the parens in the print;)).

Even still, it’s a bit of a pain: the x is referenced four times.

Answered by WestCoastProjects

Solution #4

This, in my opinion, is the most attractive version:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]
for x in filter(lambda w: w in a, xyz):
  print x

If you don’t want to utilize lambda, you can use partial function application and the operator module instead (that provides functions of most operators).
from operator import contains
from functools import partial
print(list(filter(partial(contains, a), xyz)))

Answered by Alexander Oh

Solution #5

I’d most likely use:

for x in xyz: 
    if x not in a:

Answered by Wim Feijen

Post is based on