Search code examples
pythonlistnumpysum

sum on np.array vs python list: unsupported operand type(s) for %: 'list' and 'int'


I need to sum over an indicator function in a set.

sum() can be directly used on np.array with no issues.

import numpy as np
y = np.arange(10)
ans = sum(y % 2 == 0)

However, sum() cannot be used directly on python lists.

z = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ans = sum(z % 2 == 0)

On the other hand, this works for np.array and python lists.

ans = sum(each % 2 == 0 for each in z)
print(ans)

The question is why? Both np.array and python lists should be iterables. What makes np.array support the additional syntax?


Solution

  • It's because Python list doesn't implement that out of the box, if you want, you can always subclass python list and have own custom list to allow modulo operation via __mod__ method:

    class MyList(list):
        def __mod__(self, i):
            return [item%i for item in self]
        
    >> data = MyList([1,2,3,4,5,6,7,8,9])
    >> data%3
    
    [1, 2, 0, 1, 2, 0, 1, 2, 0]
    

    You can take a look at official Python documentation to know about the methods that can be overwritten.