# loops condition - Pythonic way to combine FOR loop and IF statement

while combining (8)

Use `intersection` or `intersection_update`

• intersection :

``````a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]
ans = sorted(set(a).intersection(set(xyz)))
``````
• intersection_update:

``````a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]
b = set(a)
b.intersection_update(xyz)
``````

then `b` is your answer

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 use a list comprehension to combine these when the statements are simple, such as:

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

But what I can't find is a good example anywhere (to copy and learn from) demonstrating a complex set of commands (not just "print x") that occur following a combination of a for loop and some if statements. Something that I would expect looks like:

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

Is this just not the way python is supposed to work?

You can use generators too, if generator expressions become too involved or complex:

``````def gen():
for x in xyz:
if x in a:
yield x

for x in gen():
print x
``````

The following is a simplification/one liner from 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
``````

Notice that the `generator` was kept inline. This was tested on `python2.7` and `python3.6` (notice the parens in the `print` ;) )

You can use generator expressions like this:

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

for x in gen:
print x
``````

I personally think this is the prettiest 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
``````

### Edit

if you are very keen on avoiding to use lambda you can use partial function application and use the operator module (that provides functions of most operators).

https://docs.python.org/2/library/operator.html#module-operator

``````from operator import contains
from functools import partial
print(list(filter(partial(contains, a), xyz)))
``````

``````a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]
set(a) & set(xyz)
set([0, 9, 4, 6, 7])
``````

As per The Zen of Python (if you are wondering whether your code is "Pythonic", that's the place to go):

• Beautiful is better than ugly.
• Explicit is better than implicit.
• Simple is better than complex.
• Flat is better than nested.

The Pythonic way of getting the `sorted` `intersection` of two `set`s is:

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

Or those elements that are `xyz` but not in `a`:

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

But for a more complicated loop you may want to flatten it by iterating over a well-named generator expression and/or calling out to a well-named function. Trying to fit everything on one line is rarely "Pythonic".

I'm not sure what you are trying to do with `enumerate`, but if `a` is a dictionary, you probably want to use the keys, like this:

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

A metaclass is a class that tells how (some) other class should be created.

This is a case where I saw metaclass as a solution to my problem: I had a really complicated problem, that probably could have been solved differently, but I chose to solve it using a metaclass. Because of the complexity, it is one of the few modules I have written where the comments in the module surpass the amount of code that has been written. Here it is...

``````#!/usr/bin/env python

# This requires some explaining.  The point of this metaclass excercise is to
# create a static abstract class that is in one way or another, dormant until
# queried.  I experimented with creating a singlton on import, but that did
# not quite behave how I wanted it to.  See now here, we are creating a class
# called GsyncOptions, that on import, will do nothing except state that its
# class creator is GsyncOptionsType.  This means, docopt doesn't parse any
# of the help document, nor does it start processing command line options.
# So importing this module becomes really efficient.  The complicated bit
# comes from requiring the GsyncOptions class to be static.  By that, I mean
# any property on it, may or may not exist, since they are not statically
# defined; so I can't simply just define the class with a whole bunch of
# properties that are @property @staticmethods.
#
# So here's how it works:
#
# Executing 'from libgsync.options import GsyncOptions' does nothing more
# than load up this module, define the Type and the Class and import them
# into the callers namespace.  Simple.
#
# Invoking 'GsyncOptions.debug' for the first time, or any other property
# causes the __metaclass__ __getattr__ method to be called, since the class
# is not instantiated as a class instance yet.  The __getattr__ method on
# the type then initialises the class (GsyncOptions) via the __initialiseClass
# method.  This is the first and only time the class will actually have its
# dictionary statically populated.  The docopt module is invoked to parse the
# usage document and generate command line options from it.  These are then
# paired with their defaults and what's in sys.argv.  After all that, we
# setup some dynamic properties that could not be defined by their name in
# the usage, before everything is then transplanted onto the actual class
# object (or static class GsyncOptions).
#
# Another piece of magic, is to allow command line options to be set in
# in their native form and be translated into argparse style properties.
#
# Finally, the GsyncListOptions class is actually where the options are
# stored.  This only acts as a mechanism for storing options as lists, to
# allow aggregation of duplicate options or options that can be specified
# multiple times.  The __getattr__ call hides this by default, returning the
# last item in a property's list.  However, if the entire list is required,
# calling the 'list()' method on the GsyncOptions class, returns a reference
# to the GsyncListOptions class, which contains all of the same properties
# but as lists and without the duplication of having them as both lists and
# static singlton values.
#
# So this actually means that GsyncOptions is actually a static proxy class...
#
# ...And all this is neatly hidden within a closure for safe keeping.
def GetGsyncOptionsType():
class GsyncListOptions(object):
__initialised = False

class GsyncOptionsType(type):
def __initialiseClass(cls):
if GsyncListOptions._GsyncListOptions__initialised: return

from docopt import docopt
from libgsync.options import doc
from libgsync import __version__

options = docopt(
doc.__doc__ % __version__,
version = __version__,
options_first = True
)

paths = options.pop('<path>', None)
setattr(cls, "destination_path", paths.pop() if paths else None)
setattr(cls, "source_paths", paths)
setattr(cls, "options", options)

for k, v in options.iteritems():
setattr(cls, k, v)

GsyncListOptions._GsyncListOptions__initialised = True

def list(cls):
return GsyncListOptions

def __getattr__(cls, name):
cls.__initialiseClass()
return getattr(GsyncListOptions, name)[-1]

def __setattr__(cls, name, value):
# Substitut option names: --an-option-name for an_option_name
import re
name = re.sub(r'^__', "", re.sub(r'-', "_", name))
listvalue = []

# Ensure value is converted to a list type for GsyncListOptions
if isinstance(value, list):
if value:
listvalue = [] + value
else:
listvalue = [ None ]
else:
listvalue = [ value ]

type.__setattr__(GsyncListOptions, name, listvalue)

# Cleanup this module to prevent tinkering.
import sys
module = sys.modules[__name__]
del module.__dict__['GetGsyncOptionsType']

return GsyncOptionsType

# Our singlton abstract proxy class.
class GsyncOptions(object):
__metaclass__ = GetGsyncOptionsType()
``````