On Fri, 21 Jan 2005 17:04:11 -0800, Jeff Shannon <[EMAIL PROTECTED]> wrote:
>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) > >>> Or >>> a, b, c, d, e = ('a:b:c'.split(':')+[None]*4)[:5] >>> print (a, b, c, d, e) ('a', 'b', 'c', None, None) You could even be profligate and use *5 in place of that *4, if that makes an easier idiom ;-) Works if there's too many too: >>> a, b = ('a:b:c'.split(':')+[None]*2)[:2] >>> print (a, b) ('a', 'b') > >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. > That gives me an idea: >>> def foo(a=None, b=None, c=None, d=None, e=None, *ignore): ... return a, b, c, d, e ... >>> a, b, c, d, e = foo(*'a:b:c'.split(':')) >>> print (a, b, c, d, e) ('a', 'b', 'c', None, None) But then, might as well do: >>> def bar(nreq, *args): ... if nreq <= len(args): return args[:nreq] ... return args+ (nreq-len(args))*(None,) ... >>> a, b, c, d, e = bar(5, *'a:b:c'.split(':')) >>> print (a, b, c, d, e) ('a', 'b', 'c', None, None) >>> a, b = bar(2, *'a:b:c'.split(':')) >>> print (a, b) ('a', 'b') >>> a, b, c = bar(3, *'a:b:c'.split(':')) >>> print (a, b, c) ('a', 'b', 'c') But usually, I would like n + tail, where I know n is a safe bet, e.g., >>> def ntail(n, *args): ... return args[:n]+(args[n:],) ... >>> a, b, t = ntail(2, *'a:b:c:d:e'.split(':')) >>> print (a, b, t) ('a', 'b', ('c', 'd', 'e')) >>> a, b, t = ntail(2, *'a:b'.split(':')) >>> print (a, b, t) ('a', 'b', ()) People have asked to be able to spell that as a, b, *t = 'a:b:c:d:e'.split(':') Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list