Python's sum()
function is really useful and generic except for its requrement for the start
argument (sum(iterable, /, start=0)
), which defaults to 0. With this, we can only sum iterables that support addition with integers. Otherwise, we are to define start explicitly. This affects readability and sometimes leads to unnecessary calculations.
Consider the following example: let's say we want to sum iterable of some nontrivial objects such as sympy's matrices (well, if one is not familiar with sympy they can treat sp.Matrix
as object which supports summation but not with integers). The following code will fail:
import sympy as sp
a = sp.Matrix([1, 2])
b = sp.Matrix([3, 4])
sum([a, b]) #TypeError: cannot add <class 'sympy.matrices.dense.MutableDenseMatrix'> and <class 'int'>
How can we repair this? Let's try writing a specific function:
from typing import List
def sum_matrices(ms: List[sp.Matrix]) -> sp.Matrix:
return sum(ms, 0*ms[0])
However, this only works because we can define some analogue of zero element. If we were unable to do that, it would be much easier to implement another generic sum()
without a requrement for start rather than try finding different 'starts' every time. Moreover, multiplying by zero might be quite an expensive operation if size of matrices is huge. Creating a zero matrix from the beginning requires some lines of code. Though the aim of sum()
is to reduce amount of boilerplate.
So, the questions are:
- Why did they even think of this start argument? How can this be helpful at all? At least, they could've made it
start=None
and then check whether summation should start with the first element of iterable (ifstart == None
) or withstart
otherwise. - What is the best way to deal with such situations?