Python Function for Aggregating Iterables with FillValue

  • Share this:

Code introduction


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)