list comprehensions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Elaine Jackson

    list comprehensions


    List comprehensions don't work the way you intuitively expect them to work. I
    realize many people have no intuitions about how list comprehensions 'should'
    work, so if you recognize yourself in this description, feel free to go back to
    whatever you were doing before. If you're still here, though, I invite you to
    consider the following definition:

    partitions = lambda n: [[n]]+[[k]+x for x in partitions(n-k) for k in
    range(1,n)]

    As defined above, the function raises an exception when you call it ('k'
    referenced before assignment). For the sake of clarity, here is workable code
    expressing the same intention:

    def partitions(n):
    reVal=[[n]]
    for k in range(1,n):
    for x in partitions(n-k):
    reVal.append([k]+x)
    return reVal

    So I guess what I want to ask is: Can somebody explain the semantics of list
    comprehensions to me? Or even better: Can somebody tell me where to look in the
    documentation to find out about list comprehensions? All donations gratefully
    received.

    Peace


  • Daniel Dittmar

    #2
    Re: list comprehensions

    Elaine Jackson wrote:[color=blue]
    > List comprehensions don't work the way you intuitively expect them to work. I[/color]

    How can you say such a thing. 100 Haskell programmers have been asked
    about Python list comprehension and all found it intuitive.
    [color=blue]
    > partitions = lambda n: [[n]]+[[k]+x for x in partitions(n-k) for k in
    > range(1,n)]
    >
    > As defined above, the function raises an exception when you call it ('k'
    > referenced before assignment).[/color]

    Try a simpler example and you'll see the order of execution with nested
    loops:[color=blue][color=green][color=darkred]
    >>> [(a, x) for a in "ab" for x in "xy"][/color][/color][/color]
    [('a', 'x'), ('a', 'y'), ('b', 'x'), ('b', 'y')]
    [color=blue]
    > So I guess what I want to ask is: Can somebody explain the semantics of list
    > comprehensions to me? Or even better: Can somebody tell me where to look in the
    > documentation to find out about list comprehensions? All donations gratefully
    > received.[/color]

    http://www.python.org/doc/2.3.3/ref/lists.html, especially "each of the
    for or if clauses a block, nesting from left to right".
    [color=blue][color=green][color=darkred]
    >>> partitions = lambda n: [[n]]+[[k]+x for k in range(1,n) for x in[/color][/color][/color]
    partitions(n-k)][color=blue][color=green][color=darkred]
    >>> partitions (3)[/color][/color][/color]
    [[3], [1, 2], [1, 1, 1], [2, 1]]

    Daniel

    Comment

    • Terry Reedy

      #3
      Re: list comprehensions


      "Elaine Jackson" <elainejackson7 355@home.com> wrote in message
      news:yjZcc.4282 3$Pk3.9547@pd7t w1no...[color=blue]
      >
      > List comprehensions don't work the way you intuitively expect them to[/color]
      work.

      One of my pet posting peeves is when people ascribe their own
      characteristics to others, as when they write 'you' when they really mean,
      or should have meant, 'I'. But nevermind.
      [color=blue]
      > I realize many people have no intuitions about how list comprehensions[/color]
      'should'[color=blue]
      > work,[/color]

      List comprehensions are sufficiently 'artificial' that I would advise
      anyone to avoid the temptation to intuit how they work without consulting
      the manual, tutorials, or other written explanations.

      The Python Reference Manual Index, section L, entry List..comprehen sions
      takes one to subsection 5.2.4 List displays. The last two sentences
      therein read

      "When a list comprehension is supplied, it consists of a single expression
      followed by at least one for clause and zero or more for or if clauses. In
      this case, 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."

      OK, takes a couple of readings and maybe some working examples.
      [color=blue]
      > partitions = lambda n: [[n]]+[[k]+x for x in partitions(n-k) for k in
      > range(1,n)]
      >
      > As defined above, the function raises an exception when you call it ('k'
      > referenced before assignment).[/color]

      Of course, you have the two for clauses reversed, as the error message
      might suggest to an experienced Pythoneer. As the manual specifies, for/if
      clauses nest *left to right*. To match the double loop below, you want
      instead

      [[k]+x for k in range(1,n) for x in partitions(n-k)]
      [color=blue]
      > def partitions(n):
      > reVal=[[n]]
      > for k in range(1,n):
      > for x in partitions(n-k):
      > reVal.append([k]+x)
      > return reVal[/color]

      Terry J. Reedy




      Comment

      Working...