Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > default value in a list

Reply
Thread Tools

default value in a list

 
 
TB
Guest
Posts: n/a
 
      01-21-2005
Hi,

Is there an elegant way to assign to a list from a list of unknown
size? For example, how could you do something like:

>>> a, b, c = (line.split(':'))

if line could have less than three fields?

Thanks,
TB

 
Reply With Quote
 
 
 
 
Steve Holden
Guest
Posts: n/a
 
      01-21-2005
TB wrote:

> Hi,
>
> Is there an elegant way to assign to a list from a list of unknown
> size? For example, how could you do something like:
>
>
>>>> a, b, c = (line.split(':'))

>
> if line could have less than three fields?
>

l = line.split(':')

l is a list, whose length will be one more than the number of colons in
the line.

You can access the elements of the list using a[0], a[2], and so on. For
example:

>>> line = "This:is:a:sample:line"
>>> l = line.split(':')
>>> l

['This', 'is', 'a', 'sample', 'line']
>>> for w in l:

... print w
...
This
is
a
sample
line
>>> len(l)

5
>>>


regards
Steve
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/
Holden Web LLC +1 703 861 4237 +1 800 494 3119
 
Reply With Quote
 
 
 
 
Larry Bates
Guest
Posts: n/a
 
      01-21-2005
What do you want put into the "missing" variables?
I'll assume None. Something like following
works:

values=line.split(':')
try: a=values.pop(0)
except IndexError: a=None
try: b=values.pop(0)
except IndexError: b=None
try: c=values.pop(0)
except IndexError: c=None


Larry Bates



TB wrote:
> Hi,
>
> Is there an elegant way to assign to a list from a list of unknown
> size? For example, how could you do something like:
>
>
>>>> a, b, c = (line.split(':'))

>
> if line could have less than three fields?
>
> Thanks,
> TB
>

 
Reply With Quote
 
Paul McGuire
Guest
Posts: n/a
 
      01-21-2005
"TB" <> wrote in message
news: ups.com...
> Hi,
>
> Is there an elegant way to assign to a list from a list of unknown
> size? For example, how could you do something like:
>
> >>> a, b, c = (line.split(':'))

> if line could have less than three fields?
>
> Thanks,
> TB
>

I asked a very similar question a few weeks ago, and from the various
suggestions, I came up with this:

line = "AAAA:BBB"
expand = lambda lst,default,minlen : (lst + [default]*minlen)[0:minlen]
a,b,c = expand( line.split(":"), "", 3 )
print a
print b
print c

-- Paul


 
Reply With Quote
 
Steven Bethard
Guest
Posts: n/a
 
      01-22-2005
Paul McGuire wrote:
> expand = lambda lst,default,minlen : (lst + [default]*minlen)[0:minlen]


Or if you're afraid of lambda like me:

def expand(lst,default,minlen):return (lst + [default]*minlen)[0:minlen]

or perhaps more readably:

def expand(lst, default, minlen):
return (lst + [default]*minlen)[0:minlen]

No need for an anonymous function when you're naming it.

Steve
 
Reply With Quote
 
Jeff Shannon
Guest
Posts: n/a
 
      01-22-2005
TB wrote:

> Hi,
>
> Is there an elegant way to assign to a list from a list of unknown
> size? For example, how could you do something like:
>
>
>>>> a, b, c = (line.split(':'))

>
> if line could have less than three fields?


(Note that you're actually assigning to a group of local variables,
via tuple unpacking, not assigning to a list...)

One could also do something like this:

>>> l = "a:b:c".split(':')
>>> a, b, c, d, e = l + ([None] * (5 - len(l)))
>>> print (a, b, c, d, e)

('a', 'b', 'c', None, None)
>>>


Personally, though, I can't help but think that, if you're not certain
how many fields are in a string, then splitting it into independent
variables (rather than, say, a list or dict) *cannot* be an elegant
solution. If the fields deserve independent names, then they must
have a definite (and distinct) meaning; if they have a distinct
meaning (as opposed to being a series of similar items, in which case
you should keep them in a list), then which field is it that's
missing? Are you sure it's *always* the last fields? This feels to
me like the wrong solution to any problem.

Hm, speaking of fields makes me think of classes.

>>> class LineObj:

.... def __init__(self, a=None, b=None, c=None, d=None, e=None):
.... self.a = a
.... self.b = b
.... self.c = c
.... self.d = d
.... self.e = e
....
>>> l = "a:b:c".split(':')
>>> o = LineObj(*l)
>>> o.__dict__

{'a': 'a', 'c': 'c', 'b': 'b', 'e': None, 'd': None}
>>>


This is a bit more likely to be meaningful, in that there's almost
certainly some logical connection between the fields of the line
you're splitting and keeping them as a class demonstrates that
connection, but it still seems a bit smelly to me.

Jeff Shannon
Technician/Programmer
Credit International


 
Reply With Quote
 
Fredrik Lundh
Guest
Posts: n/a
 
      01-22-2005
Paul McGuire wrote:

> I asked a very similar question a few weeks ago, and from the various
> suggestions, I came up with this:
>
> expand = lambda lst,default,minlen : (lst + [default]*minlen)[0:minlen]


I wouldn't trust whoever suggested that. if you want a function, use a function:

def expand(seq, default, minlen):
return (seq + [default]*minlen)[:minlen]

</F>



 
Reply With Quote
 
Alex Martelli
Guest
Posts: n/a
 
      01-22-2005
TB <> wrote:

> Is there an elegant way to assign to a list from a list of unknown
> size? For example, how could you do something like:
>
> >>> a, b, c = (line.split(':'))

> if line could have less than three fields?


import itertools as it

a, b, c = it.islice(
it.chain(
line.split(':'),
it.repeat(some_default),
),
3)

I find itertools-based solutions to be generally quite elegant.

This one assumes you want to assign some_default to variables in the LHS
target beyond the length of the RHS list. If what you want is to repeat
the RHS list over and over instead, this simplifies the first argument
of islice:

a, b, c = it.islice(it.cycle(line.split(':')), 3)

Of course, you can always choose to write your own generator instead of
building it up with itertools. itertools solutions tend to be faster,
and I think it's good to get familiar with that precious modules, but
without such familiarity many readers may find a specially coded
generator easier to follow. E.g.:

def pad_with_default(N, iterable, default=None):
it = iter(iterable)
for x in it:
if N<=0: break
yield x
N -= 1
while N>0:
yield default
N -= 1

a, b, c = pad_with_default(3, line.split(':'))


The itertools-based solution hinges on a higher level of abstraction,
glueing and tweaking iterators as "atoms"; the innards of a custom coded
generator tend to be programmed at a lower level of abstraction,
reasoning in item-by-item mode. There are pluses and minuses to each
approach; I think in the long range higher abstraction pays off, so it's
worth the investment to train yourself to use itertools.


In the Python Cookbook new 2nd edition, due out in a couple months,
we've added a whole new chapter about iterators and generators, since
it's such a major subfield in today's Python (as evidenced by the wealth
of recipes submitted to Activestate's online cookbook sites on the
subject). A couple of recipes have do with multiple unpacking
assignment -- one of them, in particular, is an evil hack which peers
into the caller's bytecode to find out how many items are on the LHS, so
you don't have to pass that '3' explicitly. I guess that might be
considered "elegant", for suitably contorted meanings of "elegant"...
it's on the site, too, but I don't have the URL at hand. It's
instructive, anyway, but I wouldn't suggest actually using it in any
kind of production code...


Alex
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      01-22-2005
Paul McGuire wrote:

>> Is there an elegant way to assign to a list from a list of unknown
>> size? For example, how could you do something like:
>>
>> >>> a, b, c = (line.split(':'))

>> if line could have less than three fields?


> I asked a very similar question a few weeks ago, and from the various
> suggestions, I came up with this:
>
> line = "AAAA:BBB"
> expand = lambda lst,default,minlen : (lst + [default]*minlen)[0:minlen]
> a,b,c = expand( line.split(":"), "", 3 )


Here is an expand() variant that is not restricted to lists but works with
arbitrary iterables:

from itertools import chain, repeat, islice

def expand(iterable, length, default=None):
return islice(chain(iterable, repeat(default)), length)

Peter




 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      01-22-2005
Peter Otten wrote:

> Paul McGuire wrote:
>
>>> Is there an elegant way to assign to a list from a list of unknown
>>> size? For example, how could you do something like:
>>>
>>> >>> a, b, c = (line.split(':'))
>>> if line could have less than three fields?

>
>> I asked a very similar question a few weeks ago, and from the various
>> suggestions, I came up with this:
>>
>> line = "AAAA:BBB"
>> expand = lambda lst,default,minlen : (lst + [default]*minlen)[0:minlen]
>> a,b,c = expand( line.split(":"), "", 3 )

>
> Here is an expand() variant that is not restricted to lists but works with
> arbitrary iterables:
>
> from itertools import chain, repeat, islice
>
> def expand(iterable, length, default=None):
> return islice(chain(iterable, repeat(default)), length)


Also nice, IMHO, is allowing individual defaults for different positions in
the tuple:

>>> def expand(items, defaults):

.... if len(items) >= len(defaults):
.... return items[:len(defaults)]
.... return items + defaults[len(items):]
....
>>> expand((1, 2, 3), (10, 20, 30, 40))

(1, 2, 3, 40)
>>> expand((1, 2, 3), (10, 20))

(1, 2)

Peter

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What value should be passed to make a function use the default argument value? LaundroMat Python 50 10-14-2006 05:11 AM
setting default value for template parameter list bluekite2000@gmail.com C++ 6 06-22-2005 11:24 AM
Using default a empty dictionary as a default value C Gillespie Python 3 03-22-2005 12:22 PM
default value for list access? Bo Peng Python 4 02-27-2005 09:39 PM
Easy way to output a default value if <xsl:value-of/> selection comes back empty? Michael Ahlers XML 1 07-12-2004 05:17 PM



Advertisments