Bug in list comprehensions?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Iain King

    #1

    Bug in list comprehensions?

    I was playing with list comprehensions, to try and work out how doubled
    up versions work (like this one from another thread: [i for i in
    range(9) for j in range(i)]). I think I've figured that out, but I
    found something strange along the way:
    [color=blue][color=green][color=darkred]
    >>> alpha = ["one", "two", "three"]
    >>> beta = ["A", "B", "C"]
    >>> [x for x in alpha for y in beta][/color][/color][/color]
    ['one', 'one', 'one', 'two', 'two', 'two', 'three', 'three', 'three'][color=blue][color=green][color=darkred]
    >>> [x for x in y for y in beta][/color][/color][/color]
    ['C', 'C', 'C'][color=blue][color=green][color=darkred]
    >>> beta = [alpha, alpha, alpha]
    >>> beta[/color][/color][/color]
    [['one', 'two', 'three'], ['one', 'two', 'three'], ['one', 'two',
    'three']][color=blue][color=green][color=darkred]
    >>> [x for x in y for y in beta][/color][/color][/color]
    ['C', 'C', 'C'][color=blue][color=green][color=darkred]
    >>> [y for y in beta][/color][/color][/color]
    [['one', 'two', 'three'], ['one', 'two', 'three'], ['one', 'two',
    'three']][color=blue][color=green][color=darkred]
    >>> [x for x in y for y in beta][/color][/color][/color]
    ['one', 'one', 'one', 'two', 'two', 'two', 'three', 'three', 'three']

    Shoudn't both lines '[x for x in y for y in beta]' produce the same
    list?
    I'm guessing I'm the one confused here... but I'm confused! What's
    going on?

    Iain

  • Duncan Booth

    #2
    Re: Bug in list comprehensions?

    Iain King wrote:
    [color=blue][color=green][color=darkred]
    >>>> [x for x in y for y in beta][/color][/color]
    > ['C', 'C', 'C'][color=green][color=darkred]
    >>>> [y for y in beta][/color][/color]
    > [['one', 'two', 'three'], ['one', 'two', 'three'], ['one', 'two',
    > 'three']][color=green][color=darkred]
    >>>> [x for x in y for y in beta][/color][/color]
    > ['one', 'one', 'one', 'two', 'two', 'two', 'three', 'three', 'three']
    >
    > Shoudn't both lines '[x for x in y for y in beta]' produce the same
    > list?[/color]

    [x for x in y for y in beta] is a shorthand for:

    tmp = []
    for x in y:
    for y in beta:
    tmp.append(x)

    So x iterates over whatever y is before the loop starts, and y iterates
    over beta (but that doesn't affect what x is iterating over).

    The important thing is to remember that the order of 'for' and 'if'
    statements is the same as though you had written the for loop out in full.

    Comment

    • Fredrik Lundh

      #3
      Re: Bug in list comprehensions?

      Iain King wrote:
      [color=blue]
      > I'm guessing I'm the one confused here... but I'm confused! What's
      > going on?[/color]

      reading the documentation may help:

      /.../ the elements of the new list are those that would be produced
      by considering each of the for or if clauses a block, nesting from left
      to right, and evaluating the expression to produce a list element each
      time the innermost block is reached.

      the clauses nest from left to right, not from right to left, so "[x for
      x in y for y in beta]" is equivalent to

      out = []
      for x in y:
      for y in beta:
      out.append(x)

      </F>

      Comment

      • Sion Arrowsmith

        #4
        Re: Bug in list comprehensions?

        Fredrik Lundh <fredrik@python ware.com> wrote:[color=blue]
        >Iain King wrote:[color=green]
        >> I'm guessing I'm the one confused here... but I'm confused! What's
        >> going on?[/color]
        >the clauses nest from left to right, not from right to left, so "[x for
        >x in y for y in beta]" is equivalent to
        >
        > out = []
        > for x in y:
        > for y in beta:
        > out.append(x)[/color]

        And a list comprehension doesn't get a namespace to itself (cf.
        generator comprehensions) so "leaks" its variables. Exactly as
        above. So the y being iterated over in "for x in y" is the y
        from the previous inner iteration ("for y in beta").

        --
        \S -- siona@chiark.gr eenend.org.uk -- http://www.chaos.org.uk/~sion/
        ___ | "Frankly I have no feelings towards penguins one way or the other"
        \X/ | -- Arthur C. Clarke
        her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump

        Comment

        Working...