## Finding the index of a numpy array in a list

Question

```
import numpy as np
foo = [1, "hello", np.array([[1,2,3]]) ]
```

I would expect

```
foo.index( np.array([[1,2,3]]) )
```

to return

```
2
```

but instead I get

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

anything better than my current solution? It seems inefficient.

```
def find_index_of_array(list, array):
for i in range(len(list)):
if np.all(list[i]==array):
return i
find_index_of_array(foo, np.array([[1,2,3]]) )
# 2
```

Show source

## Answers ( 4 )

The reason for the error here is obviously because numpy's ndarray overrides

`==`

to return an array rather than a boolean.AFAIK, there is no simple solution here. The following will work so long as the

`np.all(val == array)`

bit works.Whether that bit works or not depends critically on what the other elements in the array are and if they can be compared with numpy arrays.

For performance, you might want to process only the NumPy arrays in the input list. So, we could type-check before going into the loop and index into the elements that are arrays.

Thus, an implementation would be -

How about this one?

Output:Note: This will also work even if

`foo`

is a list. I just put it as a`numpy`

array here.The issue here (you probably know already but just to repeat it) is that

`list.index`

works along the lines of:The line

`if item == wanted_item`

is the problem, because it implicitly converts`item == wanted_item`

to a boolean. But`numpy.ndarray`

(except if it's a scalar) raises this`ValueError`

then:## Solution 1: adapter (thin wrapper) class

I generally use a thin wrapper (adapter) around

`numpy.ndarray`

whenever I need to use python functions like`list.index`

:These thin wrappers are more expensive than manually using some

`enumerate`

loop or comprehension but you don't have to re-implement the python functions. Assuming the list contains only numpy-arrays (otherwise you need to do some`if ... else ...`

checking):After this step you can use all your python functions on this list:

These wrappers are not numpy-arrays anymore but you have thin wrappers so the extra list is quite small. So depending on your needs you could keep the wrapped list and the original list and choose on which to do the operations, for example you can also

`list.count`

the identical arrays now:or

`list.remove`

:## Solution 2: subclass and

`ndarray.view`

This approach uses explicit subclasses of

`numpy.array`

. It has the advantage that you get all builtin array-functionality and only modify the requested operation (which would be`__eq__`

):Again you get most list methods this way:

`list.remove`

,`list.count`

besides`list.index`

.However this approach may yield subtle behaviour if some operation implicitly uses

`__eq__`

. You can always re-interpret is as plain numpy array by using`np.asarray`

or`.view(np.ndarray)`

:## Alternative: Overriding

`__bool__`

(or`__nonzero__`

for python 2)Instead of fixing the problem in the

`__eq__`

method you could also override`__bool__`

or`__nonzero__`

:Again this makes the

`list.index`

work like intended:But this will definitly modify more behaviour! For example: