Is there a better algorithm?

Discussion in 'Python' started by Bruno Desthuilliers, Jan 2, 2009.

  1. Kottiyath a écrit :
    > I have the following list of tuples:
    > L = [(1, 2), (3, 4, 5), (6, 7)]
    >
    > I want to loop through the list and extract the values.
    > The only algorithm I could think of is:
    >>>> for i in l:

    > ... u = None
    > ... try:
    > ... (k, v) = i
    > ... except ValueError:
    > ... (k, u, v) = i
    > ... print k, u, v
    > ---------
    > 1 None 2
    > 3 4 5
    > 6 None 7
    > -------------
    > But, this algorithm doesnt look very beautiful - like say -> for k, u,
    > v in L:
    > Can anyone suggest a better algorithm to get the values?


    complement = lambda t: (t[0], None, t[1]) if len(t) == 2 else t
    for k, u, v in map(complement, L):
    print k, u, v
     
    Bruno Desthuilliers, Jan 2, 2009
    #1
    1. Advertising

  2. Bruno Desthuilliers

    Kottiyath Guest

    I have the following list of tuples:
    L = [(1, 2), (3, 4, 5), (6, 7)]

    I want to loop through the list and extract the values.
    The only algorithm I could think of is:
    >>> for i in l:

    .... u = None
    .... try:
    .... (k, v) = i
    .... except ValueError:
    .... (k, u, v) = i
    .... print k, u, v
    ---------
    1 None 2
    3 4 5
    6 None 7
    -------------
    But, this algorithm doesnt look very beautiful - like say -> for k, u,
    v in L:
    Can anyone suggest a better algorithm to get the values?
     
    Kottiyath, Jan 2, 2009
    #2
    1. Advertising

  3. Bruno Desthuilliers

    Fuzzyman Guest

    On Jan 2, 6:11 pm, Kottiyath <> wrote:
    > I have the following list of tuples:
    > L = [(1, 2), (3, 4, 5), (6, 7)]
    >
    > I want to loop through the list and extract the values.
    > The only algorithm I could think of is:>>> for i in l:
    >
    > ...  u = None
    > ...  try:
    > ...   (k, v) = i
    > ...  except ValueError:
    > ...   (k, u, v) = i
    > ...  print k, u, v
    > ---------
    > 1 None 2
    > 3 4 5
    > 6 None 7
    > -------------
    > But, this algorithm doesnt look very beautiful - like say -> for k, u,
    > v in L:
    > Can anyone suggest a better algorithm to get the values?


    for i in l:
    u = None
    if len(i) == 2:
    k, v = i
    else:
    k, u, v = i

    Best I could come up with.

    Alternatively:

    def mangle(i):
    if len(i) == 3:
    return i
    k, v = i
    return k, None, v

    for i in l:
    k, u, v = mangle(i)

    I'm sure there is a clever one liner using the Python 2.5 ternary
    expression syntax. On the other hand I'm not sure it would be very
    readable, so a straightforward (if less clever) solution is probably
    better.

    Michael
    --
    http://www.ironpythoninaction.com/
     
    Fuzzyman, Jan 2, 2009
    #3
  4. Bruno Desthuilliers

    Steve Holden Guest

    Kottiyath wrote:
    > I have the following list of tuples:
    > L = [(1, 2), (3, 4, 5), (6, 7)]
    >
    > I want to loop through the list and extract the values.
    > The only algorithm I could think of is:
    >>>> for i in l:

    > ... u = None
    > ... try:
    > ... (k, v) = i
    > ... except ValueError:
    > ... (k, u, v) = i
    > ... print k, u, v
    > ---------
    > 1 None 2
    > 3 4 5
    > 6 None 7
    > -------------
    > But, this algorithm doesnt look very beautiful - like say -> for k, u,
    > v in L:
    > Can anyone suggest a better algorithm to get the values?


    L = [(1, 2), (3, 4, 5), (6, 7)]
    for i in L:
    if len(i) == 2:
    k, v, u = i + (None, )
    else:
    k, u, v = i
    print k, u, v

    regards
    Steve
    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    Holden Web LLC http://www.holdenweb.com/
     
    Steve Holden, Jan 2, 2009
    #4
  5. Hi,

    Fuzzyman wrote:

    > I'm sure there is a clever one liner using the Python 2.5 ternary
    > expression syntax. On the other hand I'm not sure it would be very
    > readable, so a straightforward (if less clever) solution is probably
    > better.


    that would be something like this (using a generator)

    L = [(1, 2), (3, 4, 5), (6, 7)]
    g = ( ((e[0],None,e[1]) if len(e)==2 else (e[0],e[1],e[2])) for e in L)

    for elem in g:
    print elem

    So long,
    Markus
    P.S: No, I don't consider that more readable than your example ;-)
    --
    "Hacking is like having sex: you get in, you get out and you hope that you
    did not leave anything which can be traced back to you" - Unbekannt
     
    Markus Brueckner, Jan 2, 2009
    #5
  6. Kottiyath ha scritto:
    > I have the following list of tuples:
    > L = [(1, 2), (3, 4, 5), (6, 7)]
    >
    > I want to loop through the list and extract the values.
    > The only algorithm I could think of is:
    >>>> for i in l:

    > ... u = None
    > ... try:
    > ... (k, v) = i
    > ... except ValueError:
    > ... (k, u, v) = i
    > ... print k, u, v
    > ---------
    > 1 None 2
    > 3 4 5
    > 6 None 7
    > -------------
    > But, this algorithm doesnt look very beautiful - like say -> for k, u,
    > v in L:
    > Can anyone suggest a better algorithm to get the values?


    One way to avoid explicit checks on tuple size (but making the code a
    bit less clear and probably slower):

    for i in l:
    k, v, u = (i[:3]+(None,))[:3]
    ...

    Ciao
    -----
    FB
     
    Francesco Bochicchio, Jan 2, 2009
    #6
  7. On Fri, 02 Jan 2009 19:55:43 +0100 Markus Brueckner <>
    wrote:

    > g = ( ((e[0],None,e[1]) if len(e)==2 else (e[0],e[1],e[2])) for e in
    > L)


    If this isn't proof of Python's versatility, I don't know what is. In
    one line it can mimic both Lisp and Perl. Sweet.

    :)
    /W

    --
    My real email address is constructed by swapping the domain with the
    recipient (local part).
     
    Andreas Waldenburger, Jan 2, 2009
    #7
  8. Kottiyath <> writes:

    > I have the following list of tuples:
    > L = [(1, 2), (3, 4, 5), (6, 7)]
    >
    > I want to loop through the list and extract the values.
    > The only algorithm I could think of is:
    >>>> for i in l:

    > ... u = None
    > ... try:
    > ... (k, v) = i
    > ... except ValueError:
    > ... (k, u, v) = i
    > ... print k, u, v
    > ---------
    > 1 None 2
    > 3 4 5
    > 6 None 7
    > -------------
    > But, this algorithm doesnt look very beautiful - like say -> for k, u,
    > v in L:
    > Can anyone suggest a better algorithm to get the values?


    Just a note: this isn't really an algorithm problem. ;)

    It's more of a grammar obstruction.

    To make your code more simple, it would be nice if the assignment
    operator would return, "None," in the case where there are too few
    values to unpack from the right-operand of the assignment operator.

    Aside from the typical workarounds that first came to mind, I started
    wondering whether it was possible to expose the problem and solve it
    directly.

    Sadly, it appears to be non-trivial (or at least, well hidden from the
    unwashed masses).

    I'd be really curious if the unpacking machinery were exposed to the
    developer. I started poking around the operator and types modules, but
    the implementation isn't obvious. What methods are being called on the
    operands by the assignment operator in the following statement:

    a, b, c = some_tuple

    I'm sorry if this line of inquiry is not very pythonic; but one is
    curious if this is some python magic happening here. After using the
    idiom for years I hadn't really thought about it much until recently.
     
    J Kenneth King, Jan 2, 2009
    #8
  9. Bruno Desthuilliers

    Paul Rubin Guest

    Kottiyath <> writes:
    > I have the following list of tuples:
    > L = [(1, 2), (3, 4, 5), (6, 7)]
    > I want to loop through the list and extract the values.


    Others have suggested messy ways to code what you're asking. At another
    level, that list format seems like a code smell. You may be better off
    organizing the program so that

    L = [(1, None, 2), (3, 4, 5), (6, None, 7)]

    after which unpacking becomes trivial.
     
    Paul Rubin, Jan 2, 2009
    #9
  10. Bruno Desthuilliers

    Guest

    Fuzzyman:

    > for i in l:
    >    u = None
    >    if len(i) == 2:
    >       k, v = i
    >    else:
    >        k, u, v = i


    That's the best solution I have seen in this thread so far (but I
    suggest to improve indents and use better variable names). In
    programming it's generally better to follow the KISS principle.

    Bye,
    bearophile
     
    , Jan 2, 2009
    #10
  11. Paul Rubin <http://> writes:

    > Kottiyath <> writes:
    >> I have the following list of tuples:
    >> L = [(1, 2), (3, 4, 5), (6, 7)]
    >> I want to loop through the list and extract the values.

    >
    > Others have suggested messy ways to code what you're asking. At another
    > level, that list format seems like a code smell. You may be better off
    > organizing the program so that
    >
    > L = [(1, None, 2), (3, 4, 5), (6, None, 7)]
    >
    > after which unpacking becomes trivial.


    Very true. +1
     
    J Kenneth King, Jan 2, 2009
    #11
  12. Kottiyath wrote:
    > I have the following list of tuples:
    > L = [(1, 2), (3, 4, 5), (6, 7)]
    >
    > I want to loop through the list and extract the values.
    > The only algorithm I could think of is: [...]


    If this is part of a real program, instead of an exercise, you should
    fix the code that creates this list of tuples so that they have a
    uniform length of 3. And if the third element is missing, it should be None.

    This saves lots of trouble later on.

    -- Gerhard
     
    Gerhard Häring, Jan 2, 2009
    #12
  13. Bruno Desthuilliers

    Ned Deily Guest

    In article <>,
    J Kenneth King <> wrote:
    > Kottiyath <> writes:
    > > I have the following list of tuples:
    > > L = [(1, 2), (3, 4, 5), (6, 7)]
    > >
    > > I want to loop through the list and extract the values.
    > > The only algorithm I could think of is:
    > >>>> for i in l:

    > > ... u = None
    > > ... try:
    > > ... (k, v) = i
    > > ... except ValueError:
    > > ... (k, u, v) = i
    > > ... print k, u, v
    > > ---------
    > > 1 None 2
    > > 3 4 5
    > > 6 None 7
    > > -------------
    > > But, this algorithm doesnt look very beautiful - like say -> for k, u,
    > > v in L:
    > > Can anyone suggest a better algorithm to get the values?

    >
    > Just a note: this isn't really an algorithm problem. ;)
    >
    > It's more of a grammar obstruction.
    >
    > To make your code more simple, it would be nice if the assignment
    > operator would return, "None," in the case where there are too few
    > values to unpack from the right-operand of the assignment operator.


    Looks like the extended iterable unpacking feature of Python 3.0,
    described in PEP 3132, comes to the rescue here:

    >>> L = [(1, 2), (3, 4, 5), (6, 7)]
    >>> for i in L:

    .... k, *u, v = i
    .... print(k, u, v)
    ....
    1 [] 2
    3 [4] 5
    6 [] 7

    --
    Ned Deily,
     
    Ned Deily, Jan 2, 2009
    #13
  14. Bruno Desthuilliers

    Aaron Brady Guest

    On Jan 2, 12:11 pm, Kottiyath <> wrote:
    > I have the following list of tuples:
    > L = [(1, 2), (3, 4, 5), (6, 7)]
    >
    > I want to loop through the list and extract the values.
    > The only algorithm I could think of is:>>> for i in l:
    >
    > ...  u = None
    > ...  try:
    > ...   (k, v) = i
    > ...  except ValueError:
    > ...   (k, u, v) = i
    > ...  print k, u, v
    > ---------
    > 1 None 2
    > 3 4 5
    > 6 None 7
    > -------------
    > But, this algorithm doesnt look very beautiful - like say -> for k, u,
    > v in L:
    > Can anyone suggest a better algorithm to get the values?


    for i in L:
    k, u, v= i[ 0 ], i[ 1 ], i[ -1 ]
    if len( i )== 2: u= None
     
    Aaron Brady, Jan 2, 2009
    #14
  15. Bruno Desthuilliers

    mr Guest

    As has been noted, the best is to fix the input to be regular-3-
    tuples. For the fun of it, here's another variation of a solution:

    tuples = [(1, 2), (3, 4, 5), (6, 7)]

    def triple_or_pair(seq):
    u = None
    try:
    k, u, v = seq
    except ValueError:
    k, v = seq
    return k, u, v

    for k, u, v in [ triple_or_pair(seq) for seq in tuples ]:
    print k, u, v
     
    mr, Jan 2, 2009
    #15
  16. Bruno Desthuilliers

    Kottiyath Guest

    On Jan 3, 2:38 am, mr <> wrote:
    > As has been noted, the best is to fix the input to be regular-3-
    > tuples. For the fun of it, here's another variation of a solution:
    >
    > tuples = [(1, 2), (3, 4, 5), (6, 7)]
    >
    > def triple_or_pair(seq):
    >     u = None
    >     try:
    >         k, u, v = seq
    >     except ValueError:
    >         k, v = seq
    >     return k, u, v
    >
    > for k, u, v in [ triple_or_pair(seq) for seq in tuples ]:
    >     print k, u, v


    It is a code to post some data to HTML server.
    Even though usually the POST values are of type(name, value), if file
    transfer is involved, then POST values change to (name, filename,
    value).
    My view was that since filename is a rare occurance and doesnt make
    sense in a usual POST, I had not kept it as a full 3 tuple.
    Since so many programmers (that too much more capable than me) are
    suggesting that it is code smell, I am reviewing my decision.
     
    Kottiyath, Jan 3, 2009
    #16
  17. bearophile wrote:

    >Fuzzyman:
    >
    >> for i in l:
    >> u = None
    >> if len(i) == 2:
    >> k, v = i
    >> else:
    >> k, u, v = i

    >
    >That's the best solution I have seen in this thread so far (but I
    >suggest to improve indents and use better variable names). In
    >programming it's generally better to follow the KISS principle.


    Strange that nobody has suggested:

    for Tup in Lst:
    for item in Tup:
    print item,
    print

    Because if I recall correctly, all the OP was doing was printing the stuff.

    Gets a bit hairier if you want to return the values though. - if you
    replace the first print statement above with a yield and delete the
    second, bare print, you lose knowledge of which tuple the item
    belongs to.

    It is not trivial to do if you don't have a priori knowledge of
    the maximum and minimum tuple length.

    Seems to me it is one of those gems that is a PITA to do completely
    generally - basically because you don't know when you call it how
    many items to unpack - so you have to return a count or something,
    or just fall back on a two step approach - get the tuple from the list,
    then do something with the items in the tuple.

    - Hendrik
     
    Hendrik van Rooyen, Jan 3, 2009
    #17
  18. En Sat, 03 Jan 2009 02:55:12 -0200, Kottiyath <>
    escribió:

    >> tuples = [(1, 2), (3, 4, 5), (6, 7)]

    >
    > It is a code to post some data to HTML server.
    > Even though usually the POST values are of type(name, value), if file
    > transfer is involved, then POST values change to (name, filename,
    > value).
    > My view was that since filename is a rare occurance and doesnt make
    > sense in a usual POST, I had not kept it as a full 3 tuple.
    > Since so many programmers (that too much more capable than me) are
    > suggesting that it is code smell, I am reviewing my decision.


    What about using another data structure instead - like this:

    class entry:
    filename = None

    def __init__(self, name, value, filename=None):
    self.name = name
    self.value = value
    if filename is not None:
    self.filename = filename

    [entry('name', 'Gabriel'), entry('age', 18), entry('pic', picture_data,
    'path/to/file')]

    --
    Gabriel Genellina
     
    Gabriel Genellina, Jan 6, 2009
    #18
  19. Bruno Desthuilliers

    Lie Guest

    On Jan 3, 4:38 am, mr <> wrote:
    > As has been noted, the best is to fix the input to be regular-3-
    > tuples. For the fun of it, here's another variation of a solution:
    >

    <snip>

    Yet another solution:

    for i in l:
    k, u, v = i[0], None if len(i) == 2 else i[1], i[-1]
     
    Lie, Jan 13, 2009
    #19
  20. Bruno Desthuilliers

    Lie Guest

    On Jan 3, 11:55 am, Kottiyath <> wrote:
    > On Jan 3, 2:38 am, mr <> wrote:
    >

    <snip>
    > It is a code to post some data to HTML server.
    > Even though usually the POST values are of type(name, value), if file
    > transfer is involved, then POST values change to (name, filename,
    > value).
    > My view was that since filename is a rare occurance and doesnt make
    > sense in a usual POST, I had not kept it as a full 3 tuple.
    > Since so many programmers (that too much more capable than me) are
    > suggesting that it is code smell, I am reviewing my decision.


    Is it possible to change (name, filename, value) into (name, value,
    filename) instead?

    In most cases optional arguments should be last. There are some very
    exceptional case, where early optional argument might be better, like
    python's range, which type signature is: [[start,] stop[, step]] (i.e.
    with one argument, it is assigned to stop, instead of start)
     
    Lie, Jan 13, 2009
    #20
    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. Ahmed Moustafa
    Replies:
    0
    Views:
    780
    Ahmed Moustafa
    Nov 15, 2003
  2. Bapaiah Katepalli
    Replies:
    1
    Views:
    1,498
    Mike Treseler
    Jun 23, 2006
  3. Peter Bencsik
    Replies:
    2
    Views:
    835
  4. In Search for a better Algorithm

    , Sep 28, 2007, in forum: C Programming
    Replies:
    10
    Views:
    473
    Charlie Gordon
    Sep 29, 2007
  5. Replies:
    39
    Views:
    1,648
    Charlie Gordon
    Nov 12, 2007
Loading...

Share This Page