# Getting indices of an array in Python

## Question:

I have a numpy array `A`

with `True, False`

elements. I want to print all indices which have `False`

element. But, I am getting an error. I present the expected output:

```
import numpy as np
A=np.array([[False],
[False],
[ True],
[False],
[False]])
for i in range(0,len(A)):
if (A[i]==['False']):
print(i)
```

The error is :

```
FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
if (A[i]==['False']):
```

The expected output is :

```
[0,1,3,4]
```

## Answers:

Rather than iterating over the array, you can build an index array using `np.arange`

, and then slice the indices using the boolean array.

```
np.arange(len(A))[~A.ravel()]
# returns:
array([0, 1, 3, 4])
```

If you want it with the same dimensionality as `A`

, you can use `np.argwhere`

```
np.argwhere(~A.ravel())
# returns:
array([[0],
[1],
[3],
[4]], dtype=int64)
```

you are comparing list with boolean value i.e True/False with list with string value i.e ‘False’, hence you are getting the error.

Change the if condition as follows (i.e. without quotation marks for False):

if (A[i] == [False])

You can also use np.where:

```
A=np.array([[False],
[False],
[ True],
[False],
[False]])
print(np.where(np.squeeze(A)==False))
```

Note: `np.squeeze`

just removes the last dimension of your array.

The output is `array([0, 1, 3, 4]`

as expected.

.nonzero()

will give you those indices.

```
>>> A
array([[False],
[False],
[ True],
[False],
[False]])
>>> ~A
array([[ True],
[ True],
[False],
[ True],
[ True]])
>>>
>>> (~A).nonzero()[0]
array([0, 1, 3, 4])
>>>
>>>
>>> np.flatnonzero(~A)
array([0, 1, 3, 4])
```

You could get those indices in one shot using argwhere:

```
indices = np.argwhere(A==False)[:,0] # extract only row indexes from output
print(indices)
# [0 1 3 4]
```

Using np.where with unpacking could also work:

```
indices,_ = np.where(A==False)
print(indices)
# [0 1 3 4]
```

You can use list comprehension as well.

`enumerate`

is considered more pythonic than `range(len(A))`

```
[i for i,j in enumerate(A) if A[i]==[False]]
#[0, 1, 3, 4]
```

**What’s wrong in you code?**

In every iteration of your loop your arrays are of type `bool`

, and you are trying to compare with a `list(str)`

. For Numpy to make the comparison it must cast types. But Numpy will only perform the comparison if it can safely cast dtypes (see this answer). Although Python 3 can cast `bool('anything')`

to `True`

, Numpy don’t find it safe. Why? I don’t know, but see how this can be funny:

```
>>> bool('False') == True
True
```

**And how to make element-wise comparison using two different dtype arrays? choose one type to cast**

Note that you’ll get the same warning if you: `np.array(['False']) == False`

.

For element-wise comparison you can use `np.equal(array1, array2, dtype=your_type)`

:

```
>>> compare = np.array(len(A)*(('False',),))
>>> compare
array([['False'],
['False'],
['False'],
['False'],
['False']], dtype='<U5')
>>> np.equal(A, compare, dtype=bool)
UFuncTypeError: Cannot cast ufunc 'equal' input 1 from dtype('<U5') to dtype('bool') with casting rule 'same_kind'
```

With that it throws an error you can handle if it’d be the case.

Therefore the comparison can’t be performed since the types can’t be cast. Which can be checked using `np.can_cast`

:

```
>>> np.can_cast('<U5', bool)
False
```

**How to fix your code?**

There are already so many great answers, and you can simply choose any and you’ll probably be ok. But here is my contribution in case you want to maintain a similar syntax:

```
for idx, element in enumerate(A):
if not element:
print(idx)
```

Here, `enumerate`

concatenates every element of `A`

with an counting index, and the `not element`

will return True every time `element`

is `False`

.

But in case of best performance always prefer using Numpy’s functions:

```
>>> compare = np.array(len(A)*((False,),))
>>> np.where(np.equal(A, compare))[0]
array([0, 1, 3, 4])
```