You can download this code by clicking the button below.
This code is now available for download.
This function takes multiple iterable objects and aggregates them into a single iterable. If the iterables are of uneven length, missing values are filled with `fillvalue`.
Technology Stack : itertools, collections
Code Type : Function
Code Difficulty : Intermediate
def zip_longest(*args, fillvalue=None):
# This function takes several iterables and aggregates them into a single iterable.
# If the iterables are of uneven length, missing values are filled with `fillvalue`.
import itertools
import collections
def _all_almost_equal(iterable, value):
return all(x == value for x in iterable)
def _zip_longest(*iterables, fillvalue=None):
# Create a list of iterators for each of the iterables
iterators = [iter(it) for it in iterables]
# Create a counter for each of the iterators to track the number of values each has produced
counters = collections.Counter(iterators)
# Loop until all iterators are exhausted
while iterators:
# Find the iterator with the smallest counter
smallest = min(iterators, key=counters.get)
# Get the next value from the iterator, or fillvalue if the iterator is exhausted
value = next(smallest, fillvalue)
# If the value is fillvalue and all iterators are equal, we can stop the iteration
if value == fillvalue and _all_almost_equal(iterators, fillvalue):
break
# Yield the value and increment the counter for the iterator
yield value
# Increment the counter for the iterator
counters[smallest] += 1
# Remove the iterator from the list if it is exhausted
if not next(smallest, fillvalue):
iterators.remove(smallest)
return _zip_longest(*args, fillvalue=fillvalue)