list unpack trick?

Discussion in 'Python' started by aurora, Jan 22, 2005.

  1. aurora

    aurora Guest

    I find that I use some list unpacking construct very often:

    name, value = s.split('=',1)

    So that 'a=1' unpack as name='a' and value='1' and 'a=b=c' unpack as
    name='a' and value='b=c'.

    The only issue is when s does not contain the character '=', let's say it
    is 'xyz', the result list has a len of 1 and the unpacking would fail. Is
    there some really handy trick to pack the result list into len of 2 so
    that it unpack as name='xyz' and value=''?

    So more generally, is there an easy way to pad a list into length of n
    with filler items appended at the end?
     
    aurora, Jan 22, 2005
    #1
    1. Advertising

  2. On Fri, Jan 21, 2005 at 08:02:38PM -0800, aurora wrote:
    > I find that I use some list unpacking construct very often:
    >
    > name, value = s.split('=',1)
    >
    > So that 'a=1' unpack as name='a' and value='1' and 'a=b=c' unpack as
    > name='a' and value='b=c'.
    >
    > The only issue is when s does not contain the character '=', let's say it
    > is 'xyz', the result list has a len of 1 and the unpacking would fail. Is
    > there some really handy trick to pack the result list into len of 2 so
    > that it unpack as name='xyz' and value=''?


    what about:
    s.find( '=' )!=-1 and s.split( '=', 1 ) or [s,'']

    bye bye - sifu
     
    Siegmund Fuehringer, Jan 22, 2005
    #2
    1. Advertising

  3. "aurora" wrote:

    > The only issue is when s does not contain the character '=', let's say it is 'xyz', the result
    > list has a len of 1 and the unpacking would fail. Is there some really handy trick to pack the
    > result list into len of 2 so that it unpack as name='xyz' and value=''?


    do you need a trick? spelling it out works just fine:

    try:
    key, value = field.split("=", 1)
    except:
    key = field; value = ""

    or

    if "=" in field:
    key, value = field.split("=", 1)
    else:
    key = field; value = ""

    (the former might be slightly more efficient if the "="-less case is uncommon)

    or, if you insist:

    key, value = re.match("([^=]*)(?:=(.*))?", field).groups()

    or

    key, value = (field + "="["=" in field:]).split("=", 1)

    but that's not really worth the typing. better do

    key, value = splitfield(field)

    with a reasonable definition of splitfield (I recommend the try-except form).

    > So more generally, is there an easy way to pad a list into length of n with filler items appended
    > at the end?


    some variants (with varying semantics):

    list = (list + n*[item])[:n]

    or

    list += (n - len(list)) * [item]

    or (readable):

    if len(list) < n:
    list.extend((n - len(list)) * [item])

    etc.

    </F>
     
    Fredrik Lundh, Jan 22, 2005
    #3
  4. Fredrik Lundh <> wrote:
    ...
    > or (readable):
    >
    > if len(list) < n:
    > list.extend((n - len(list)) * [item])


    I find it just as readable without the redundant if guard -- just:

    alist.extend((n - len(alist)) * [item])

    of course, this guard-less version depends on N*[x] being the empty list
    when N<=0, but AFAIK that's always been the case in Python (and has
    always struck me as a nicely intuitive semantics for that * operator).

    itertools-lovers may prefer:

    alist.extend(itertools.repeat(item, n-len(alist)))

    a bit less concise but nice in its own way (itertools.repeat gives an
    empty iterator when its 2nd argument is <=0, of course).


    Alex
     
    Alex Martelli, Jan 22, 2005
    #4
  5. Alex Martelli wrote:

    >> or (readable):
    >>
    >> if len(list) < n:
    >> list.extend((n - len(list)) * [item])

    >
    > I find it just as readable without the redundant if guard -- just:
    >
    > alist.extend((n - len(alist)) * [item])


    the guard makes it obvious what's going on, also for a reader that doesn't
    know exactly how "*" behaves for negative counts. once you've seen the
    "compare length to limit" and "extend", you don't have to parse the rest of
    the statement.

    </F>
     
    Fredrik Lundh, Jan 22, 2005
    #5
  6. Fredrik Lundh <> wrote:

    > Alex Martelli wrote:
    >
    > >> or (readable):
    > >>
    > >> if len(list) < n:
    > >> list.extend((n - len(list)) * [item])

    > >
    > > I find it just as readable without the redundant if guard -- just:
    > >
    > > alist.extend((n - len(alist)) * [item])

    >
    > the guard makes it obvious what's going on, also for a reader that doesn't
    > know exactly how "*" behaves for negative counts.


    It does, but it's still redundant, like, say,
    if x < 0:
    x = abs(x)
    makes things obvious even for a reader not knowing exactly how abs
    behaves for positive arguments. Redundancy in the code to try and
    compensate for a reader's lack of Python knowledge is not, IMHO, a
    generally very productive strategy. I understand perfectly well that
    you and others may disagree, but I just thought it worth stating my
    personal opinion in the matter.

    > once you've seen the
    > "compare length to limit" and "extend", you don't have to parse the rest of
    > the statement.


    Sorry, I don't get this -- it seems to me that I _do_ still have to
    "parse the rest of the statement" to understand exactly what alist is
    being extended by.


    Alex
     
    Alex Martelli, Jan 22, 2005
    #6
  7. aurora

    aurora Guest

    Thanks. I'm just trying to see if there is some concise syntax available
    without getting into obscurity. As for my purpose Siegmund's suggestion
    works quite well.

    The few forms you have suggested works. But as they refer to list multiple
    times, it need a separate assignment statement like

    list = s.split('=',1)

    I am think more in the line of string.ljust(). So if we have a
    list.ljust(length, filler), we can do something like

    name, value = s.split('=',1).ljust(2,'')

    I can always break it down into multiple lines. The good thing about list
    unpacking is its a really compact and obvious syntax.



    On Sat, 22 Jan 2005 08:34:27 +0100, Fredrik Lundh <>
    wrote:
    ....
    >> So more generally, is there an easy way to pad a list into length of n
    >> with filler items appended
    >> at the end?

    >
    > some variants (with varying semantics):
    >
    > list = (list + n*[item])[:n]
    >
    > or
    >
    > list += (n - len(list)) * [item]
    >
    > or (readable):
    >
    > if len(list) < n:
    > list.extend((n - len(list)) * [item])
    >
    > etc.
    >
    > </F>
     
    aurora, Jan 22, 2005
    #7
  8. aurora

    Nick Coghlan Guest

    aurora wrote:
    > I am think more in the line of string.ljust(). So if we have a
    > list.ljust(length, filler), we can do something like
    >
    > name, value = s.split('=',1).ljust(2,'')


    Eh?

    Py> s.split('=',1).ljust(2,'')
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    AttributeError: 'list' object has no attribute 'ljust'

    Cheers,
    Nick.

    --
    Nick Coghlan | | Brisbane, Australia
    ---------------------------------------------------------------
    http://boredomandlaziness.skystorm.net
     
    Nick Coghlan, Jan 23, 2005
    #8
  9. Nick Coghlan wrote:

    >> I am think more in the line of string.ljust(). So if we have a list.ljust(length, filler), we
    >> can do something like
    >>
    >> name, value = s.split('=',1).ljust(2,'')

    >
    > Eh?
    >
    > Py> s.split('=',1).ljust(2,'')
    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > AttributeError: 'list' object has no attribute 'ljust'


    I think the "if we have" was hypothetical.

    I still don't see why the OP cannot just write a small helper and be
    done with it, but then I don't know anything about how Python is
    used, so I might be wrong ;-)

    </F>
     
    Fredrik Lundh, Jan 23, 2005
    #9
  10. On Sun, 23 Jan 2005 15:43:43 +1000, Nick Coghlan <> wrote:

    >aurora wrote:
    >> I am think more in the line of string.ljust(). So if we have a
    >> list.ljust(length, filler), we can do something like
    >>
    >> name, value = s.split('=',1).ljust(2,'')

    >
    >Eh?
    >
    >Py> s.split('=',1).ljust(2,'')
    >Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    >AttributeError: 'list' object has no attribute 'ljust'
    >


    Python 2.4b1 (#56, Nov 3 2004, 01:47:27)
    [GCC 3.2.3 (mingw special 20030504-1)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> help(''.ljust)

    Help on built-in function ljust:

    ljust(...)
    S.ljust(width[, fillchar]) -> string

    Return S left justified in a string of length width. Padding is
    done using the specified fill character (default is a space).

    I should upgrade too ;-)

    Regards,
    Bengt Richter
     
    Bengt Richter, Jan 23, 2005
    #10
  11. On Sun, 23 Jan 2005 08:22:36 GMT, (Bengt Richter) wrote:

    >On Sun, 23 Jan 2005 15:43:43 +1000, Nick Coghlan <> wrote:
    >
    >>aurora wrote:
    >>> I am think more in the line of string.ljust(). So if we have a
    >>> list.ljust(length, filler), we can do something like
    >>>
    >>> name, value = s.split('=',1).ljust(2,'')

    >>
    >>Eh?
    >>
    >>Py> s.split('=',1).ljust(2,'')
    >>Traceback (most recent call last):
    >> File "<stdin>", line 1, in ?
    >>AttributeError: 'list' object has no attribute 'ljust'
    >>

    >
    > Python 2.4b1 (#56, Nov 3 2004, 01:47:27)
    > [GCC 3.2.3 (mingw special 20030504-1)] on win32
    > Type "help", "copyright", "credits" or "license" for more information.
    > >>> help(''.ljust)

    > Help on built-in function ljust:
    >
    > ljust(...)
    > S.ljust(width[, fillchar]) -> string
    >
    > Return S left justified in a string of length width. Padding is
    > done using the specified fill character (default is a space).
    >
    >I should upgrade too ;-)
    >

    And learn to read instead of jumping to conclusions ;-/
    No ljust for *LIST* objects, D'oh.

    Regards,
    Bengt Richter
     
    Bengt Richter, Jan 23, 2005
    #11
  12. aurora

    aurora Guest

    On Sat, 22 Jan 2005 10:03:27 -0800, aurora <> wrote:

    > I am think more in the line of string.ljust(). So if we have a
    > list.ljust(length, filler), we can do something like
    >
    > name, value = s.split('=',1).ljust(2,'')
    >
    > I can always break it down into multiple lines. The good thing about
    > list unpacking is its a really compact and obvious syntax.


    Just to clarify the ljust() is a feature wish, probably should be named
    something like pad().

    Also there is another thread a few hours before this asking about
    essentially the same thing.

    "default value in a list"
    http://groups-beta.google.com/group/comp.lang.python/browse_frm/thread/f3affefdb4272270
     
    aurora, Jan 23, 2005
    #12
    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. Christian Lair
    Replies:
    0
    Views:
    418
    Christian Lair
    Feb 9, 2004
  2. Stacy Mader
    Replies:
    4
    Views:
    855
    Ekkehard Morgenstern
    Nov 22, 2003
  3. Nx
    Replies:
    3
    Views:
    337
  4. srinivasan srinivas
    Replies:
    0
    Views:
    260
    srinivasan srinivas
    Sep 14, 2008
  5. Gary Herron
    Replies:
    2
    Views:
    324
    Tim Chase
    Sep 14, 2008
Loading...

Share This Page