Get index in the list of objects by attribute in Python

Question:

I have list of objects with attribute id and I want to find index of object with specific id. I wrote something like this:

index = -1
for i in range(len(my_list)):
    if my_list[i].id == 'specific_id'
        index = i
        break

but it doesn’t look very well. Are there any better options?

Asked By: sebaszw

||

Answers:

You can use enumerate:

for index, item in enumerate(my_list):
    if item.id == 'specific_id':
        break
Answered By: Daniel Roseman

Use enumerate when you want both the values and indices in a for loop:

for index, item in enumerate(my_list):
    if item.id == 'specific_id':
        break
else:
    index = -1

Or, as a generator expression:

index = next((i for i, item in enumerate(my_list) if item.id == 'specific_id'), -1)
Answered By: Joel Cornett

Here’s an alternative that doesn’t use an (explicit) loop, with two different approaches to generating the list of ‘id’ values from the original list.

try:
    # index = map(operator.attrgetter('id'), my_list).index('specific_id')
    index = [ x.id for x in my_list ].index('specific_id')
except ValueError:
    index = -1
Answered By: chepner

Assuming

a = [1,2,3,4]
val = 3

Do

a.index(val) if val in a else -1

For multiple occurrence, as per Azam’s comment below:

[i if val == x else -1 for i,x in enumerate(a)] 

Edit1:
For everyone commenting that its List of object, all you need is, access the id

[i if val == x.id else -1 for i,x in enumerate(a)] 
Answered By: Abhishek

Implement the __eq__ method for your class

class MyCls:
   def __init__(self, id):
       self.id = id

   def __eq__(self, other):
       # comparing with str since you want to compare
       # your object with str

       if not isinstance(other, str):
           raise TypeError("MyCls can be compared only with str")
       if other == self.id:
           return True
       return False

now you can do something like

my_list = [MyCls(i) for i in 'abcdef']
print(my_list.index('c'))

This would return the index 2. It would behave like normal list.index methods behaves. i.e If it doesn’t find the index, it will raise a ValueError

Answered By: patel deven
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.