Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the index of an item in a list of lists

I have a list of lists:

colours = [["#660000","#863030","#ba4a4a","#de7e7e","#ffaaaa"],["#a34b00","#d46200","#ff7a04","#ff9b42","#fec28d"],["#dfd248","#fff224","#eefd5d","#f5ff92","#f9ffbf"],["#006600","#308630","#4aba4a","#7ede7e","#aaffaa"]]

What's the cleanest way of searching the list and returning the position of one of the items, e.g. "#660000"?

I have looked at the index method, but that doesn't seem to unpack the list inside the list.

postion = colours.index("#660000")

gives: ValueError: ['#660000'] is not in list, not [0][0] as I expect...

like image 232
Jay Gattuso Avatar asked Mar 04 '12 09:03

Jay Gattuso


People also ask

How do you find the index of an element in a list of lists?

To find the (row, column) index pair of an element in a list of lists, iterate over the rows and their indices using the enumerate() function and use the row. index(x) method to determine the index of element x in the row .

How do you find the index of an item in a list of a list in Python?

To find the index of an element in a list, you use the index() function. It returns 3 as expected. However, if you attempt to find an element that doesn't exist in the list using the index() function, you'll get an error.

How do you find an element in a list in a list?

To find an element in the list, use the Python list index() method, The index() is an inbuilt Python method that searches for an item in the list and returns its index. The index() method finds the given element in the list and returns its position.

How do you find the index of a specific string in a list Python?

By using type() operator we can get the string elements indexes from the list, string elements will come under str() type, so we iterate through the entire list with for loop and return the index which is of type string.


2 Answers

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.

like image 194
jcollado Avatar answered Oct 16 '22 06:10

jcollado


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)
like image 37
Rik Poggi Avatar answered Oct 16 '22 05:10

Rik Poggi