On 27 Nov, 12:18, boblatest <boblat...@googlemail.com> wrote: > Hello all, > > (sorry for posting from Google. I currently don't have access to my > normal nntp account.) > > Here's my question: Given a list of onknown length, I'd like to be > able to do the following: > > (a, b, c, d, e, f) = list > > If the list has fewer items than the tuple, I'd like the remaining > tuple elements to be set to "None". If the list is longer, I'd like > the excess elements to be ignored. > > The code snippet below does what I want, I was just wondering if there > was an interesting "Pythonic" way of expressing the same thing. > > Thanks, > robert > > def iter_inf(li, n): > for i in range(n): > if i < len(li): > r = li[i] > else: > r = None > i += 1 > yield r > > li = ['a', 'b', 'c'] > (a, b, c, d, e) = iter_inf(li, 5) > print a, b, c, d, e
An alternative to Peter's itertools implementation is this monstrosity... import re class name_elements: def __init__(self, iterable, *names): self.__names = set(names) if len(self.__names) != len(names): raise ValueError('names must be unique') for it, name in zip(iterable, names): if not re.match('[a-zA-Z][a-zA-Z0-9_]*', name): raise ValueError("name '%s' is not valid" % name) setattr(self, name, it) def __getattr__(self, item): if item not in self.__names: raise ValueError("name '%s' not present" % item) return self.__dict__.get(item, None) >>> res = name_elements(['a', 'b', 'c'], 'a', 'b', 'c', 'd', 'e') >>> print res.a, res.b, res.c, res.d, res.e a b c None None >>> print res.f Traceback (most recent call last): File "<pyshell#23>", line 1, in <module> print res.f File "/home/jon/rubbish.py", line 10, in __getattr__ raise AttributeError("name '%s' not present" % item) AttributeError: name 'f' not present It removes the need to know the number being unpacked (I can see this being overlooked) and the variable names could come from a list instead of being named in code. Asking for a name that doesn't exist is an exception, while all other values default to None. However, it's not totally identical to unpacking... (and most likely slower) I s'pose namedtuple could also be abused in a similar fashion. Or, if you don't mind []'ing: >>> dd = defaultdict(lambda: None) >>> dd.update(zip(['a', 'b', 'c'], range(5))) >>> print dd['a'], dd['c'], dd['blah'] 0 2 None Is it obvious I'm trying to avoid doing proper work!? Cheers, Jon. -- http://mail.python.org/mailman/listinfo/python-list