Often I need to perform multiple assignment from a sequence
(e.g. from the result of a
split()) but with some semantics
that, AFAIK, are not available in the language:
Assign N first elements and silently ignore the rest (like Perl's list assignment).
>>> a, b = 'foo bar is here'.split() >>> a, b ('foo', 'bar') >>>
Assign the remaning items to the last variable in the variable list:
>>> a, b, c = 'foo bar is here'.split() >>> a, b, c ('foo', 'bar', ['is', 'here']) >>>
If the sequence doesn't have enough values, set the variables to a default value (
Noneor any other, again similar to Perl):
>>> a, b, c, d, e = 'foo bar is here'.split() >>> a, b, c, d, e ('foo', 'bar', 'is', 'here', None) >>>
I have designed an iterator function to help me with this, but I'm concerned about my solution to this problem from the point of view of pythonic adherence:
Usefulness: Using an iterator for this kind of job is the right option, or there is something more appropriate? Or even worse: my need to do this kind of assignment in Python is not favoring other language features?
Clearness: The implementation is solid and clear enough? Or is there some other way to implement this that would be cleaner?
In other words, this solution is better discarded or can it be improved?
from itertools import * def iterassign(iterable, *, count, use_default=False, default=None, tail=False): """Iterattor for multiple assignment. :param iterable: The iterable. :param int count: The maximum count of iterations. :param bool use_default: If set, and iterable ends before max_count, continue iteration using :param:`default`. :param default: Default value to use when :param:`use_default` is set to ``True``. """ it = iter(iterable) for idx, element in enumerate(chain(islice(it, 0, count), repeat(default))): if idx >= count: break yield element else: raise StopIteration() if tail: yield list(it)
>>> ret = 'foo bar is here'.split() >>> a, b = iterassign(ret, count=2) >>> a, b ('foo', 'bar') >>> a, b, c = iterassign(ret, count=2, tail=True) >>> a, b, c ('foo', 'bar', ['is', 'here']) >>> a, b, c, d, e = iterassign(ret, count=5, use_default=True) ('foo', 'bar', 'is', 'here', None) >>>