Find the index of an item in a list of lists
I'd do something like this:
[(i, colour.index(c))
for i, colour in enumerate(colours)
if c in colour]
This will return a list of tuples where the first index is the position in the first list and second index the position in the second list (note: c
is the colour you're looking for, that is, "#660000"
).
For the example in the question, the returned value is:
[(0, 0)]
If you just need to find the first position in which the colour is found in a lazy way you can use this:
next(((i, colour.index(c))
for i, colour in enumerate(colours)
if c in colour),
None)
This will return the tuple for the first element found or None
if no element is found (you can also remove the None
argument above in it will raise a StopIteration
exception if no element is found).
Edit: As @RikPoggi correctly points out, if the number of matches is high, this will introduce some overhead because colour
is iterated twice to find c
. I assumed this to be reasonable for a low number of matches and to have an answer into a single expression. However, to avoid this, you can also define a method using the same idea as follows:
def find(c):
for i, colour in enumerate(colours):
try:
j = colour.index(c)
except ValueError:
continue
yield i, j
matches = [match for match in find('#660000')]
Note that since find
is a generator you can actually use it as in the example above with next
to stop at the first match and skip looking further.
Using enumerate()
you could write a function like this one:
def find(target):
for i,lst in enumerate(colours):
for j,color in enumerate(lst):
if color == "#660000":
return (i, j)
return (None, None)
It would be perhaps more simple using numpy
:
>>> import numpy
>>> ar = numpy.array(colours)
>>> numpy.where(ar=="#fff224")
(array([2]), array([1]))
As you see you'll get a tuple with all the row and column indexes.