I've written a little function that iterates over two iterables. The first one returns an object which is used to convert an object of the second iterable. I've got a working implementation, but would like to get some feedback.
So a simple usecase would look like this
list(serialize([String(), String()], [1, 2])) # should work
list(serialize([String(), String()], range(3))) # should fail, too many values
list(serialize([String(), String()], range(1))) # should fail, too few values
But sometimes the number of values is not known but the type is the same. Therefore infinite iterators should be allowed as types argument.
list(serialize(it.repeat(String()), range(3))) # should work
Of course finite iterators are allowed as well
list(serialize(it.repeat(String(), times=3), range(3))) # should work
list(serialize(it.repeat(String(), times=4), range(5))) # should fail
# should fail, but probably not that easy to do.
list(serialize(it.repeat(String(), times=4), range(3)))
My working implementation (except for the last case), looks like this
class String(object):
def dump(self, value):
return str(value)
def serialize(types, values):
class Stop(object):
"""Since None can be valid value we use it as fillvalue."""
if isinstance(types, collections.Sized):
# Since None is a valid value, use a different fillvalue.
tv_pairs = it.izip_longest(types, values, fillvalue=Stop)
else:
tv_pairs = it.izip(it.chain(types, (Stop,)), values)
for type, value in tv_pairs:
if type is Stop:
raise ValueError('Too many values.')
if value is Stop:
raise ValueError('Too few values.')
yield type.dump(value)
izip
? – omouse Jul 18 at 15:25