Search through a 2-dimensional list without numpy

Viewed 131

I'm looking to define a function that accepts two parameters: an int and a list.

If the function finds the integer in the list it returns its coordinates.

For example how would I do that for the number 4 in the following list, without using numpy?

l = [
         [0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 2, 1, 1, 0, 1, 1, 1, 0],
         [0, 1, 0, 1, 0, 0, 0, 1, 0],
         [0, 1, 0, 1, 1, 1, 0, 1, 0],
         [0, 1, 0, 0, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 0, 1, 0],
         [0, 0, 0, 1, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 0, 1, 0],
         [0, 1, 0, 0, 0, 0, 0, 1, 0],
         [0, 1, 0, 1, 1, 1, 0, 1, 0],
         [0, 1, 0, 1, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 1, 4, 0],
         [0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]

You can assume that the target will always show up only once and will always be contained in the list.

4 Answers

The target will always show up only once and will always be contained in the list

You can use enumerate to enumerate the outer lists and the elements of the inner lists.

def coords(lst, find):
    return next((i, j) for i, sub in enumerate(lst)
                       for j, x in enumerate(sub)
                       if x == find)

Demo with your list l:

>>> coords(l, 2)
>>> (1, 1)
>>> coords(l, 1)
>>> (1, 2)

In case you later want to adapt the function to work properly if the target is not in the list, remember that next takes an optional default argument.

You can do something like this:

l = [
         [0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 2, 1, 1, 0, 1, 1, 1, 0],
         [0, 1, 0, 1, 0, 0, 0, 1, 0],
         [0, 1, 0, 1, 1, 1, 0, 1, 0],
         [0, 1, 0, 0, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 0, 1, 0],
         [0, 0, 0, 1, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 0, 1, 0],
         [0, 1, 0, 0, 0, 0, 0, 1, 0],
         [0, 1, 0, 1, 1, 1, 0, 1, 0],
         [0, 1, 0, 1, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 1, 4, 0],
         [0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]

def findElement(element, l):
    for i in range(len(l)):
        for j in range(len(l[i])):
            if element==l[i][j]:
                return (i,j)
    return None

print(findElement(4,l))

Output:

(11, 7)

I would used solution like this:

#!/usr/bin/env ipython
# ---------------------
l = [
         [0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 2, 1, 1, 0, 1, 1, 1, 0],
         [0, 1, 0, 1, 0, 0, 0, 1, 0],
         [0, 1, 0, 1, 1, 1, 0, 1, 0],
         [0, 1, 0, 0, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 0, 1, 0],
         [0, 0, 0, 1, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 0, 1, 0],
         [0, 1, 0, 0, 0, 0, 0, 1, 0],
         [0, 1, 0, 1, 1, 1, 0, 1, 0],
         [0, 1, 0, 1, 0, 1, 0, 1, 0],
         [0, 1, 1, 1, 0, 1, 1, 4, 0],
         [0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]
# ----------------------------------
def search(value,listin):
    coords = [[ival,kkval] for ival,dd in enumerate(listin) for kkval,val in enumerate(dd) if val==value]
    return coords
# ----------------------------------
result = search(4,l)
print result

where I defined a function search, which can be used to search for certain value from an input list.

Here is my approach:

def matrix_search(target, matrix):
    for row_index, row in enumerate(matrix):
        try:
            return (row_index, row.index(target))
        except ValueError:
            pass
    raise ValueError('Target {} not found'.format(target))

Sample usage:

print(matrix_search(4, l))

Notes

  • To search a simple list, use the .index() method
  • The .index() method will either return the index of the element if found or throw a ValueError if not found. In our context, we just ignore this exception and move on to the next row.
  • At the end of the loop, we will throw an exception because the element is not found
Related