Reputation: 2202
In the code below, I create identifiers a and b that point to two separate lists with the same value, verified by their unique id values.
Then I insert both into a list, and try to find the index for b, but instead it finds the index for a.
In [21]: a = [3,2]
In [22]: b = [3,2]
In [23]: id(a)
Out[23]: 4368404136
In [24]: id(b)
Out[24]: 4368429352
In [25]: c = [[4,3], a, [5,7], b, [6,3]]
In [26]: c.index(a)
Out[26]: 1
In [27]: c.index(b)
Out[27]: 1
How can I return 3? A while loop would work but it seems like there should be a function for this.
i = 0
match = False
while (not match) and (i < len(c)):
if id(c[i]) == id(b):
print i
match = True
i += 1
Upvotes: 0
Views: 27
Reputation: 1124558
list.index()
matches values by equality, not identity.
It is easy enough to write a helper function that uses a loop, testing with the is
operator and the enumerate()
function:
def index_by_identity(lst, target):
for i, obj in enumerate(lst):
if obj is target:
return i
# no object matches
raise IndexError(target)
or, alternatively with the next()
function and a generator expression:
def index_by_identity(lst, target):
try:
return next(i for i, obj in enumerate(lst) if obj is target)
except StopIteration:
# no object matches
raise IndexError(target)
Demo:
>>> a = [3, 2]
>>> b = [3, 2]
>>> a is b
False
>>> c = [[4, 3], a, [5, 7], b, [6, 3]]
>>> def index_by_identity(lst, target):
... for i, obj in enumerate(lst):
... if obj is target:
... return i
... # no object matches
... raise IndexError(target)
...
>>> index_by_identity(c, b)
3
>>> def index_by_identity(lst, target):
... try:
... return next(i for i, obj in enumerate(lst) if obj is target)
... except StopIteration:
... # no object matches
... raise IndexError(target)
...
>>> index_by_identity(c, b)
3
Upvotes: 2