0

I was working on a mini project which I intended to use pure Python without any external library. But at a certain point, I got a TypeError like this TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'. It was as a result of trying to directly square up all elements in a list like this:

my_list = [0, 7, 2, 9] 
print(my_list ** 2)
. Although I have already created a function that could square up the list, but when I tried multiplying a numpy array like this:
import numpy as np
my_list = np.array([0, 7, 2, 9])
print(my_list ** 2)# prints array[0, 49, 4, 9]
My question is why does this happen? Or does numpy has a special property that enables it to behave like this?

5
  • You are dealing with two different data types: Numpy vs Python list. As the error states, the operator ** isn’t defined for Lists. You can write your own function that implements the operator for lists that provides the same results as Numpy. You will then have to work on vectorizing your function so that you get the same performance as Numpy. Commented May 23, 2020 at 23:56
  • my_list *2 and my_list+my_list also have different meanings (cf to numbers and ndarray) Commented May 24, 2020 at 0:48
  • In Python, operators like +, * and ** are implemented by methods attached to one or both of the arguments. Numbers most of these, lists and strings only have a few (with different meanings than numbers). Numeric dtype arrays also implement most of these operators. Operators and methods are documented for each class. Commented May 24, 2020 at 7:54
  • @hpaulj Under what circumstances would x*2 and x+x have different meanings? For all builtin numeric types as well as all sequence types these two versions are equivalent and I'd also expect them to be equivalent for ndarray objects. Commented May 25, 2020 at 10:49
  • For x being a list or string. Same result, but different from numeric calculations Commented May 25, 2020 at 11:28

1 Answer 1

2

np.ndarray defines its own dunder methods for operators such as __pow__. That's how it manages to handle those operations elementwise. With builtin lists you can use a list comprehension instead:

[x**2 for x in my_list]

You can also define your own classes that expose such custom behavior:

>>> class PowList(list):
...     def __pow__(self, other):
...         return [x**2 for x in self]
... 
>>> my_list = PowList([1, 2, 3, 4, 5])
>>> my_list ** 2
[1, 4, 9, 16, 25]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.