Add 'interleave' function to itertools?
On python-list@python.org there was a thread "make elements of a list twice or more." where the OP wanted to repeat items in a list. For example, given: [b, a, c] the output should be: [b, b, a, a, c, c] It occurred to me that this was just a special case of interleaving iterables. Going the opposite way with a list is simple enough:
numbers = [0, 1, 2, 3, 4, 5] evens = numbers[0 : : 2] odds = numbers[1 : : 2] evens [0, 2, 4] odds [1, 3, 5]
but how do you interleave them again?
[number for pair in zip(evens, odds) for number in pair] [0, 1, 2, 3, 4, 5]
I'm suggesting adding an 'interleave' function to itertools:
list(interleave(evens, odds)) [0, 1, 2, 3, 4, 5]
The function would stop when any of the iterables became exhausted (compare 'zip'). There could also be a related 'interleave_longest' function (compare 'zip_longest'). Here are the definitions: def interleave(*iterables): """Return a interleave object whose .__next__() method returns an element from each iterable argument in turn. The .__next__() method continues until the shortest iterable in the argument sequence is exhausted and then it raises StopIteration. """ sources = [iter(iterable) for iterable in iterables] try: while True: for iterable in sources: yield next(iterable) except StopIteration: pass def interleave_longest(*iterables, fillvalue=None): """Return an interleave_longest object whose .__next__() method returns an element from each iterable argument in turn. The .__next__() method continues until the longest iterable in the argument sequence is exhausted and then it raises StopIteration. When the shorter iterables are exhausted, the fillvalue is substituted in their place. The fillvalue defaults to None or can be specified by a keyword argument. """ sources = [iter(iterable) for iterable in iterables] if not sources: return remaining = len(sources) while True: for index, iterable in enumerate(sources): try: yield next(iterable) except StopIteration: remaining -= 1 if not remaining: return sources[index] = repeat(fillvalue) yield fillvalue
participants (13)
-
Andrew Barnert
-
Antoine Pitrou
-
Clay Sweetser
-
David Mertz
-
Guido van Rossum
-
Joshua Landau
-
Masklinn
-
MRAB
-
Oscar Benjamin
-
Serhiy Storchaka
-
Stefan Behnel
-
Tim Peters
-
Vito De Tullio