Reputation: 61
I have any array of values, that are often the same and I am trying to find the index of the smallest one. But I want to know all the objects that are the same.
So for example I have the array a = [1, 2, 3, 4]
and to find the index of the smallest one I use a.index(min(a))
and this returns 0. But if I had an array of a = [1, 1, 1, 1]
, using the same thing would still return 0.
I want to know that multiple indices match what I am searching for and what those indices are. How would I go about doing this?
Upvotes: 2
Views: 1566
Reputation: 46593
list.index(value)
returns the index of the first occurrence of value
in list
.
A better idea is to use a simple list comprehension and enumerate
:
indices = [i for i, x in enumerate(iterable) if x == v]
where v
is the value you want to search for and iterable
is an object that supports iterator protocol e.g. it can be a generator or a sequence (like list
).
For your specific use case, that'll look like
def smallest(seq):
m = min(seq)
return [i for i, x in enumerate(seq) if x == m]
Some examples:
In [23]: smallest([1, 2, 3, 4])
Out[23]: [0]
In [24]: smallest([1, 1, 1, 1])
Out[24]: [0, 1, 2, 3]
If you're not sure whether the seq
is empty or not, you can pass the default=-1
(or some other value) argument to min
function (in Python 3.4+):
m = min(seq, default=-1)
Consider using m = min(seq or (-1,))
(again, any value) instead, when using older Python.
Upvotes: 6
Reputation: 20831
A different approach using numpy.where could look like
In [1]: import numpy as np
In [2]: def np_smallest(seq):
...: return np.where(seq==seq.min())[0]
In [3]: np_smallest(np.array([1,1,1,1]))
Out[3]: array([0, 1, 2, 3])
In [4]: np_smallest(np.array([1,2,3,4]))
Out[4]: array([0])
This approach is slighly less efficient than the list comprehension for small list but if you face large arrays, numpy may save you some time.
In [5]: seq = np.random.randint(100, size=1000)
In [6]: %timeit np_smallest(seq)
100000 loops, best of 3: 10.1 µs per loop
In [7]: %timeit smallest(seq)
1000 loops, best of 3: 194 µs per loop
Upvotes: 1
Reputation: 145
Here is my solution:
def all_smallest(seq):
"""Takes sequence, returns list of all smallest elements"""
min_i = min(seq)
amount = seq.count(min_i)
ans = []
if amount > 1:
for n, i in enumerate(seq):
if i == min_i:
ans.append(n)
if len(ans) == amount:
return ans
return [seq.index(min_i)]
Code very straightforward I think here all clear without any explanation.
Upvotes: 0