Reputation: 986
i have next function:
def check_smaller_zeros(v):
return v < 0
When i create array with numpy i can write next code for element-by-element measurement:
v_1 = numpy.array([1, 2, -4, -1])
result = check_smaller_zeros(v_1)
# result: [False, False, True, True]
but when i try repeat it with tuple, set, frozenset and list/array reise next error:
TypeError: '<' not supported between instances of 'tuple' and 'int'
what exactly allows numpy array to have the capability for this behavior? This looks convenient, but is a bit non-obvious
Upvotes: 1
Views: 151
Reputation: 945
Python allows you to override operators with special "dunder" (double underscore) methods. For example, let's make a custom data structure that inherits from tuple
. To make <
perform item-wise comparisons, we simply need to overwrite the __lt__
method.
In [1]: class MyList(tuple):
: def __lt__(self, other):
: return tuple(v < other for v in self)
:
In [1]:
In [2]: l = MyList([1,2,3,4,5])
In [3]: l < 3
Out[3]: (True, True, False, False, False)
A list of all such methods can be found in the Python documentation under Data Model.
Upvotes: 2
Reputation: 10819
np.array is very different from tuple, lists, etc. If you want to generalize your function, you have to think about each case.
In [111]: def check_smaller_zeros(v):
...: if type(v) is np.array:
...: return v < 0
...: elif type(v) in (list, tuple):
...: return [x<0 for x in v]
...:
In [112]: check_smaller_zeros((-1,1,2,3,4,5))
Out[112]: [True, False, False, False, False, False]
In some instance, you may can simply convert the object to a np.array. But it depends form the object and you have to define the use cases in advance.
In [114]: def check_smaller_zeros(v):
...: if type(v) is np.array:
...: return v < 0
...: else:
...: return np.array(v) < 0
...:
...:
In [115]: check_smaller_zeros((-1,1,2,3,4,5))
Out[115]: array([True, False, False, False, False, False])
Upvotes: -1