# Pythonic way to combine FOR loop and IF statement

## Problem

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)
0,4,6,7,9
``````

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:
print(x...)
``````

Isn’t this how python is intended to function?

## 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:
print(x)
``````

## 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',
...     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]
...
>>> print '...but...'
...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
``````

## 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):
print(x)

12
242
``````

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.

## 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)))
``````

## Solution #5

I’d most likely use:

``````for x in xyz:
if x not in a:
print(x...)
``````