unsupported operand type error when adding objects within list using sum function

Viewed 493

I have a Serie class implemented to represent series of data and it's tag. When I add Serie objects and also numbers I get the expected output. However when I sum the same elements within a list I get following error message:

TypeError: unsupported operand type(s) for +: 'int' and 'Serie'

Toy example code

As a toy example code to understand the problem we can use:

import pandas as pd
import numpy as np

class Serie(object):

    def __str__(self):

        s = "> SERIE " + str(self.tag) + ": \n"
        s += str(self.data)
        return s

    def __init__(self, tag=None, data=pd.DataFrame()):
        """
        Creates object Serie

        @type tag: str
        @param tag: Tag for the Serie
        """
        self.tag = tag
        self.data = data

    def __add__(self, other):
        if isinstance(other, int) or isinstance(other, float):
            tag = str(other) + "+" + self.tag
            serie = Serie(tag)
            serie.data = self.data + other
        else:
            try:
                tag = self.tag + "+" + other.tag
            except:
                print ("ERROR: You can't add to somehing that is not a Serie or a number." )
                return None
            serie = Serie(tag)
            serie.data = self.data + other.data
        return serie

s1 = Serie("fibonacci",pd.Series([1,1,2,3,5,8]))
s2 = Serie("2power",pd.Series(np.linspace(1,6,6)**2))
s3 = 10
sumSerie = s1+s2+s3
print sumSerie

This prints the result as expected:

>>> 
> SERIE 10+fibonacci+2power: 
0    12.0
1    15.0
2    21.0
3    29.0
4    40.0
5    54.0
dtype: float64

Error when using sum of objects within list

However when I run following lines:

l = [s1,s2,s3]
sum(l)

I get error message:

sum(l) TypeError: unsupported operand type(s) for +: 'int' and 'Serie'

And same error message is displayed when I run:

l2 = [s1,s2]
sum(l2)

But in l2 list there is no int variable.

Questions

Why is this error message being displayed? This is confusing as I was able to sum the objects outside the list.

Is there something I can do in order to achieve performing the sum of the objects within the list?

EDIT

As suggested in the comments, I added the __radd__ to correctly overload the add method. So I added the below lines to the Serie class:

def __radd__(self,other):
    return self.__add__(other)

Then the sum works. But not as expected.

If I run the below code:

>>> print sum(l)

I get this output:

> SERIE 10+0+fibonacci+2power: 
0    12.0
1    15.0
2    21.0
3    29.0
4    40.0
5    54.0
dtype: float64

Which is definitely not the same I expected. There is a +0 extra within the tag. How can this be? However if I use the option I stated in my answer print np.array(l).sum() the result is correct.

EDIT 2

After overloading add method correctly I was suggested to use below method to perform the sum as expected:

reduce(lambda a, b: a+b, l)

This approach worked to be able to use sum function for the list and get the correct result.

As stated by pault in the comments in sum method "start defaults to 0" as detailed in sum function's documentation. That was why the extra +0 was being added to the tag before.

In conclusion I believe I would preferrably use the option using numpy.sum function instead:

np.array(l).sum()
1 Answers

Not sure why using the sum function is not possible. But a workaround to get the desired output from the lists would be to create a numpy array from the list and use numpy.sum function as you can see below:

np.array(l).sum()

This gives the sum of the objects from the list as expected.

Related