List comprehension in if clause of another list comprehension
Peter Otten
__peter__ at web.de
Fri Dec 19 12:45:56 CET 2008
Vedran Furac( wrote:
> Hi!
>
> In [69]: a = 'a b c'
> In [70]: b = 'a b, c d'
>
> In [74]: [i for i in a.split() if i not in b.split()]
> Out[74]: ['b']
>
> Everything ok.
>
> In [77]: b.split() == [i for i in b.split()]
> Out[77]: True
>
> As expected. Now, put this in the first list comprehension:
>
> In [80]: [i for i in a.split() if i not in [i for i in b.split()] ]
> Out[80]: ['d']
>
> Hmmmm... why is that?
>>> a = "abc"
>>> b = "a b, c d".split()
>>> b
['a', 'b,', 'c', 'd']
>>> [i for i in a if i not in b]
['b']
As expected, so far, but now comes the critical step:
>>> [i for i in a if i not in [i for i in b]]
['d']
The problem is that list comprehensions do not introduce a new namespace. So
the inner and the outer list comp share the same i. You can either rename
the inner i
>>> [i for i in a if i not in [k for k in b]]
['b']
or use a generator expression which does give a new namespace:
>>> list(x for x in "abc")
['a', 'b', 'c']
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> [i for i in a if i not in (i for i in b)]
['b']
Peter
More information about the Python-list
mailing list