List comprehension in if clause of another list comprehension

Discussion in 'Python' started by Vedran Furac(, Dec 19, 2008.

  1. 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?

    Regards!
    Vedran Furac(, Dec 19, 2008
    #1
    1. Advertising

  2. Vedran Furac(

    Peter Otten Guest

    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
    Peter Otten, Dec 19, 2008
    #2
    1. Advertising

  3. Peter Otten wrote:

    > 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']


    Thanks!
    Vedran Furac(, Dec 19, 2008
    #3
  4. Vedran Furac(

    Guest

    Peter Otten:
    > The problem is that list comprehensions do not introduce a new namespace.


    I think Python3 fixes this bug.

    Bye,
    bearophile
    , Dec 19, 2008
    #4
  5. On Fri, 19 Dec 2008 04:26:16 -0800, bearophileHUGS wrote:

    > Peter Otten:
    >> The problem is that list comprehensions do not introduce a new
    >> namespace.

    >
    > I think Python3 fixes this bug.


    Or removes that feature. ;-)
    Marc 'BlackJack' Rintsch, Dec 19, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. bobb
    Replies:
    0
    Views:
    341
  2. Shane Geiger
    Replies:
    4
    Views:
    374
    bullockbefriending bard
    Mar 25, 2007
  3. Debajit Adhikary
    Replies:
    17
    Views:
    672
    Debajit Adhikary
    Oct 18, 2007
  4. Ross
    Replies:
    8
    Views:
    275
    namekuseijin
    May 6, 2009
  5. Felix
    Replies:
    5
    Views:
    1,161
    Lawrence D'Oliveiro
    Oct 27, 2009
Loading...

Share This Page