Reputation: 113
I.e. Does something like the following exist?
lst = [["a", "b", "c"], [4,5,6],"test"]
print getIndex(lst, "a")
>>> 0
print getIndex(lst, 5)
>>> 1
print getIndex(lst, "test")
>>> 2
I know of the regular index() method but that only looks for the immediate elements. I have a rough solution of making a new list, parsing through the superlist and adding "y" or "n" then looking for the index of the "y" in that one, but I feel there is much better way. Thanks
Upvotes: 1
Views: 186
Reputation: 5896
def getIndex(lst,item):
for n,i in enumerate(lst):
if (type(i) == list and item in i) or i == item
return n
getIndex(lst,'test')
>>> 2
Upvotes: 0
Reputation: 22443
There is a problem with hellpanderrr's solution. It assumes that the main list elements will only be lists or strings. It fails if one searches on a list where another type is in the main list (the in
operation raises a TypeError
). E.g.:
lst2 = [["a", "b", "c"], [4, 5, 6], "test", 19]
>>> getIndex(lst2, 19)
# Ugly TypeError stack trace ensues
To fix this:
def getIndex2(lst, item):
for n, i in enumerate(lst):
try:
if item == i or item in i:
return n
except TypeError:
pass
return None
Now:
>>> getIndex2(lst2, "test")
2
>>> getIndex2(lst2, 19)
3
There are several ways to accomplish the "equals or in" test. This solution bowls right through, using a "get forgiveness not permission" idiom to catch the times when the in
on i
is not type-appropriate. It would also be possible to test the type of i
before the in
operation, or directly ask if i
supports the in operation. But direct type inspection is often frowned upon, and strings and containers in Python have some complex overlapping capabilities. The "get forgiveness" approach gracefully handles those more simply.
Note that this also explicitly handles the case where no value is found.
>>> print getIndex2(lst2, 333)
None
While functions not returning a value implicitly return None
, it is better to be explicit about such default cases.
By the by, this approach handles two levels. If the lists can be arbitrarily nested, a different approach, likely involving recursion, would be needed.
Upvotes: 2
Reputation: 94
Try using the default function to the list: list.index
l = [[1,2,3], ['a', 'b', 'c']]
l[0].index(2) # index 1
l[1].index('b') # index 1
This generates a "ValueError" if the item does not exist.
Upvotes: 0
Reputation: 5559
use a generator
e.g. in >= Python 2.6, if you know the item exists in a sublist:
idx = next(i for i,v in enumerate(lst) if item in v)
Upvotes: 1