list comprehension syntax..?

Discussion in 'Python' started by Gregory Guthrie, Aug 1, 2006.

  1. Sorry for a simple question- but I don't understand how to parse this use of
    a list comprehension.

    The "or" clauses are odd to me.

    It also seems like it is being overly clever (?) in using a lc expression as
    a for loop to drive the recursion.

    Thanks for any insight!
    Gregory
    -------------------------

    # http://markbyers.com/moinmoin/moin.cgi/ShortestSudokuSolver

    def solve(board):
    i=board.find('0') # find next open cell
    if i<0: # done if none...
    print board; exit("Done")
    [ m in [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)
    or board[j] for j in range(81) ]
    or solve(board[:i]+m+board[i+1:]) for m in'%d'%5**18 ]



    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
    Gregory Guthrie, Aug 1, 2006
    #1
    1. Advertising

  2. Gregory Guthrie

    Duncan Booth Guest

    Gregory Guthrie wrote:

    > Sorry for a simple question- but I don't understand how to parse this
    > use of a list comprehension.
    >
    > The "or" clauses are odd to me.
    >
    > It also seems like it is being overly clever (?) in using a lc
    > expression as a for loop to drive the recursion.


    You are spot on there. It is a list comprehension, but the resulting list
    is just thrown away, so using a list comprehension is a complete waste of
    time serving only to confuse the issue. Presumably it saved the author a
    character or two.

    [ exp for var in seq ]

    when the result isn't used can be rewritten as:

    for var in seq:
    exp

    and:

    exp1 or exp2

    when the result is thrown away is just:

    if not exp1:
    exp2


    So:

    [ m in [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)
    or board[j] for j in range(81) ]
    or solve(board[:i]+m+board[i+1:]) for m in'%d'%5**18 ]

    is equivalent to:

    inner = [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3) or board[j] for j in
    range(81) ]
    for m in '3814697265625':
    if m not in inner:
    solve(board[:i]+m+board[i+1:])

    (That inner list comprehension doesn't depend on m, so it doesn't need to
    be reevaluated each time round the loop except, again, to save a few
    characters.)

    The '%d'%5**18 looks to be a silly way to iterate through all possible
    digits for m even though it does some of them twice while saving one
    character over writing range(1,10).

    The strange expression I called 'inner' is a list containing the string
    value board[j] if j is in the same row, column or block as i, or an integer
    for any other cells. So 'm not in inner' is true only if the value for m is
    not already used in that row column or block and is therefore a possible
    candidate for that location in the board.
    Duncan Booth, Aug 1, 2006
    #2
    1. Advertising

  3. Gregory Guthrie

    Gary Herron Guest

    Gregory Guthrie wrote:
    > Sorry for a simple question- but I don't understand how to parse this use of
    > a list comprehension.
    >
    > The "or" clauses are odd to me.
    >
    > It also seems like it is being overly clever (?) in using a lc expression as
    > a for loop to drive the recursion.
    >
    > Thanks for any insight!
    > Gregory
    > -------------------------
    >
    > # http://markbyers.com/moinmoin/moin.cgi/ShortestSudokuSolver
    >
    > def solve(board):
    > i=board.find('0') # find next open cell
    > if i<0: # done if none...
    > print board; exit("Done")
    > [ m in [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)
    > or board[j] for j in range(81) ]
    > or solve(board[:i]+m+board[i+1:]) for m in'%d'%5**18 ]
    >


    The "or" clause (as you call it) has nothing to do with the list
    comprehension.
    The syntax being used here is
    [ big_expression for m in something]
    *and* the big_expression contains an "or" OPERATOR, with a
    complex_expression on one side and solve(...) on the other, like this
    complex_expression or solve(...)
    *and* the complex_expression contains a nested list comprehension like this
    m in nested_lc
    *and* nested_lc is
    [ugly_expression for j in range(81)]
    *and* ugly_expression contains another "or" OPERATOR with ...
    *and* sigh...

    Whoever put this expression together has made something that is
    completely unreadable, mostly unmaintainable, and not noticeably more
    efficient than code that is readable and maintainable.

    Moreover, all the work of creating the outer list seems to be wasted
    since that list is just thrown out.

    This is worse than "overly clever". Loops are for looping, list
    comprehension is for building lists. It is bad programming practice to
    use list comprehension for looping.

    Hope that helps you,
    Gary Herron

    >
    >
    > ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    > http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    > ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
    >
    Gary Herron, Aug 1, 2006
    #3
  4. Very helpful, thanks!!

    So I see that it parses as:


    m='1'
    a="asdf"
    b="1234"
    print [((m in a) or b) for m in '%d'%1234 ]


    I get it.
    Thanks,
    Greg


    "Duncan Booth" <> wrote in message
    news:Xns9812BD37F7717duncanbooth@127.0.0.1...
    > Gregory Guthrie wrote:
    >
    >> Sorry for a simple question- but I don't understand how to parse this
    >> use of a list comprehension.
    >>
    >> The "or" clauses are odd to me.
    >>
    >> It also seems like it is being overly clever (?) in using a lc
    >> expression as a for loop to drive the recursion.

    >
    > You are spot on there. It is a list comprehension, but the resulting list
    > is just thrown away, so using a list comprehension is a complete waste of
    > time serving only to confuse the issue. Presumably it saved the author a
    > character or two.
    >
    > [ exp for var in seq ]
    >
    > when the result isn't used can be rewritten as:
    >
    > for var in seq:
    > exp
    >
    > and:
    >
    > exp1 or exp2
    >
    > when the result is thrown away is just:
    >
    > if not exp1:
    > exp2
    >
    >
    > So:
    >
    > [ m in [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)
    > or board[j] for j in range(81) ]
    > or solve(board[:i]+m+board[i+1:]) for m in'%d'%5**18 ]
    >
    > is equivalent to:
    >
    > inner = [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3) or board[j] for j in
    > range(81) ]
    > for m in '3814697265625':
    > if m not in inner:
    > solve(board[:i]+m+board[i+1:])
    >
    > (That inner list comprehension doesn't depend on m, so it doesn't need to
    > be reevaluated each time round the loop except, again, to save a few
    > characters.)
    >
    > The '%d'%5**18 looks to be a silly way to iterate through all possible
    > digits for m even though it does some of them twice while saving one
    > character over writing range(1,10).
    >
    > The strange expression I called 'inner' is a list containing the string
    > value board[j] if j is in the same row, column or block as i, or an
    > integer
    > for any other cells. So 'm not in inner' is true only if the value for m
    > is
    > not already used in that row column or block and is therefore a possible
    > candidate for that location in the board.




    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
    Gregory Guthrie, Aug 1, 2006
    #4
  5. Gary Herron wrote:
    > Gregory Guthrie wrote:
    >
    >>Sorry for a simple question- but I don't understand how to parse this use of
    >>a list comprehension.
    >>
    >>The "or" clauses are odd to me.
    >>
    >>It also seems like it is being overly clever (?) in using a lc expression as
    >>a for loop to drive the recursion.
    >>
    >>Thanks for any insight!
    >>Gregory
    >>-------------------------
    >>
    >># http://markbyers.com/moinmoin/moin.cgi/ShortestSudokuSolver
    >>
    >>def solve(board):
    >> i=board.find('0') # find next open cell
    >> if i<0: # done if none...
    >> print board; exit("Done")
    >> [ m in [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)
    >> or board[j] for j in range(81) ]
    >> or solve(board[:i]+m+board[i+1:]) for m in'%d'%5**18 ]
    >>

    >
    >
    > The "or" clause (as you call it) has nothing to do with the list
    > comprehension.
    > The syntax being used here is
    > [ big_expression for m in something]
    > *and* the big_expression contains an "or" OPERATOR, with a
    > complex_expression on one side and solve(...) on the other, like this
    > complex_expression or solve(...)
    > *and* the complex_expression contains a nested list comprehension like this
    > m in nested_lc
    > *and* nested_lc is
    > [ugly_expression for j in range(81)]
    > *and* ugly_expression contains another "or" OPERATOR with ...
    > *and* sigh...
    >
    > Whoever put this expression together has made something that is
    > completely unreadable, mostly unmaintainable, and not noticeably more
    > efficient than code that is readable and maintainable.
    >
    > Moreover, all the work of creating the outer list seems to be wasted
    > since that list is just thrown out.
    >
    > This is worse than "overly clever". Loops are for looping, list
    > comprehension is for building lists. It is bad programming practice to
    > use list comprehension for looping.

    Isn't it an advantage considering speed of the execution?
    I have just compared the speed of an explicit loop with the speed of a
    list comprehension doing the same thing in another context to see it is
    much better to use the latter. In board solvers speed is vital, so isn't
    it a good practice to use a list comprehension for looping in this
    context, anyway?

    Claudio
    >
    > Hope that helps you,
    > Gary Herron
    >
    >
    >>
    >>----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    >>http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    >>----= East and West-Coast Server Farms - Total Privacy via Encryption =----
    >>
    Claudio Grondi, Aug 1, 2006
    #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. Moosebumps

    List Comprehension Syntax

    Moosebumps, Jul 10, 2004, in forum: Python
    Replies:
    35
    Views:
    830
    David Eppstein
    Jul 22, 2004
  2. Replies:
    2
    Views:
    349
    Tim Peters
    Jul 12, 2004
  3. Debajit Adhikary
    Replies:
    17
    Views:
    664
    Debajit Adhikary
    Oct 18, 2007
  4. Chris Mellon
    Replies:
    2
    Views:
    376
    Dustan
    Jan 18, 2008
  5. Vedran Furac(
    Replies:
    4
    Views:
    314
    Marc 'BlackJack' Rintsch
    Dec 19, 2008
Loading...

Share This Page