Python's functools.reduce throws an exception when the iterable passed to it yields no elements.
Here's how I currently use it:
some_list = [] # empty list should be permissible
functools.reduce(
lambda left, right: pandas.merge(left, right, on=['idx'], how='outer'),
some_list
)
This throws an exception if the list contains no elements.
What I actually want it to do is return None if the list is empty. But that can't be achieved by setting the initial value to None because None cannot be merged with a DataFrame type in the call to pandas.merge.
I could wrap this statement in a function and perform a return-early check like so:
def f(some_list):
if len(some_list) < 1:
return None
But this doesn't seem like a great solution. Is there a more elegant way to do it?
You can provide an initial value as the 3rd argument to
reduce. The initial value is used in two ways:reducesimply returns the initial value.reduceadds the initial value to the beginning of the iterable.That is, with an initial value
x,reduce(f, iterable, x)is effectively the same asreduce(f, itertools.chain([x], iterable))*.In your case, you can provide an empty dataframe as the initial value. For example,
Then
*
itertools.chainis basically the iterator version of+. Chaining together two iterators produces an iterator that produces the values from the first iterator, followed by the values from the second.