18

For a one dimensional list, the index of an item is found as follows:

 a_list = ['a', 'b', 'new', 'mpilgrim', 'new']
 a_list.index('mpilgrim')

What is the equivalent for a 2 or n dimensional list?

Edit: I have added an example to clarify: If I have a 3 dimensional list as follows

b_list = [
          [1,2],
          [3,4],
          [5,6],
          [7,8]
         ],
         [
          [5,2],
          [3,7],
          [6,6],
          [7,9]
         ]

Now lets say I want to identify a certain value in this list. If I know the index of the 1st and 2nd dimesion but don't know the zero-th index for the value I want, how do I go about finding the zero-th index?

Would it be something like:

  target_value = 7
  b_list[0].index(target_value)

With the output being an integer: 0

agf
  • 171,228
  • 44
  • 289
  • 238
Mandeep
  • 385
  • 1
  • 3
  • 12
  • 1
    You should clarify with an example what you want the equivalent of `a_list.index()` to return. The index of a flattened list? the recursive sequence of enclosing lists? ...? – mac Jun 29 '11 at 09:41

9 Answers9

22

I don't know of an automatic way to do it, but if

a = [[1,2],[3,4],[5,6]]

and you want to find the location of 3, you can do:

x = [x for x in a if 3 in x][0]

print 'The index is (%d,%d)'%(a.index(x),x.index(3))

The output is:

The index is (1,0)

Rivka
  • 823
  • 2
  • 7
  • 20
8

For two dimensional list; you can iterate over rows and using .index function for looking for item:

def find(l, elem):
    for row, i in enumerate(l):
        try:
            column = i.index(elem)
        except ValueError:
            continue
        return row, column
    return -1

tl = [[1,2,3],[4,5,6],[7,8,9]]

print(find(tl, 6)) # (1,2)
print(find(tl, 1)) # (0,0)
print(find(tl, 9)) # (2,2)
print(find(tl, 12)) # -1
utdemir
  • 26,532
  • 10
  • 62
  • 81
6

A multidimensional list is simply a list with more lists inside of it. So its indices would be lists themselves.

a = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
print a.index([2, 3, 4])
# prints 1
4
list_2d = [[1,2],[3,4],[5,6]]

element = 1

index_row = [list_2d.index(row) for row in list_2d if element in row]

index_column = [row.index(element) for row in list_2d if element in row]
Yunhe
  • 665
  • 5
  • 10
3

For multidimensional arrays:

def find(needle,haystack):
  if needle == haystack: return []
  # Strings are iterable, too
  if isinstance(haystack,str) and len(haystack)<=1: return None
  try:
    for i,e in enumerate(haystack):
      r = find(needle,e)
      if r is not None: 
        r.insert(0,i)
        return r
  except TypeError:
    pass
  return None    


ml = [[1,2,3],[4,5,6],[7,8,9]]
print find(2,ml)
ml = [3,[[1,2,3],[4,5,6],[7,8,9]]]
print find(2,ml)
ml = [[["ab", "bc", "cde"]]]
print find("d",ml)

There should be a better way to avoid the try/except block, but I could not find one: In Python, how do I determine if an object is iterable?

Community
  • 1
  • 1
daniel kullmann
  • 13,653
  • 8
  • 51
  • 67
1

You can use the following sample method too:

data = [[1, 1,2],[12,4],[6]]

def m_array_index(arr, searchItem):
    for i,x in enumerate(a):
        for j,y in enumerate(x):
            if y == searchItem:
                return i,j
    return -1,-1#not found

print m_array_index(data, 6)

Or with all occurrences(sure code could be optimized - modified to work with generators and so on - but here is just a sample):

occurrences = lambda arr, val: tuple((i,j) for i,x in enumerate(arr) for j,y in enumerate(x) if y == val) or ((-1,-1))

print occurrences(data, 1) # ((0, 0), (0, 1))
print occurrences(data, 12) # ((1, 0),)
print occurrences(data, 11) # (-1, -1)
Artsiom Rudzenka
  • 27,895
  • 4
  • 34
  • 52
0

If you want to find the list that has an item, the simplest way to do it is:

i = 4
index = b_list[0].index( filter(lambda 1D_list: i in index , b_list[0]) )

Or if you know there are more than one matches for the item, then you can do:

i = 4
indexes = []
for match in filter(lambda 1D_list: i in list, b_list[0]):
    indexes.append(b_list[0].index(match))

None of this will raise any errors but they'll only work if there is no subarray. Go here for information about the functionality of filter.

0

For n-dimensional recursive search, you can try something like this:

from copy import copy
def scope(word, list, indexes = None):
    result = []
    if not indexes:
        indexes = []
    for index, item in enumerate(list):
        try:
            current_index = indexes + [index]
            result.append(current_index + [item.index(word)])
        except ValueError:
            pass

        if type(item[0]) == type([]):
            indexes.append(index)
            result.extend(scope(word, item, copy(indexes)))

    return result

And the result is:

>>> d_list = [['a', 'b', 'new', 'mpilgrim', 'new'], [['a', 'b', 'new', 'mpilgrim', 'new'], ['b', 'd', 'new', 'mpilgrim', 'new']]]
>>> word = 'mpilgrim'
>>> result = scope(word, d_list)
[[0, 3], [1, 0, 3], [1, 1, 3]]

Probably there are better ways to do it, but that is the one I figured out without getting any library.

EDIT: Actually, it was not perfect and one library must be added. It's copy. Now it's ok.

Gandi
  • 3,522
  • 2
  • 21
  • 31
0
list1 = [10, 20, [300, 400, [5000, 6000, [1, 6000, 2]], 6000, 500], 30, 40]

print(f'Your list is {list1}')
print('---------------------------------------------------------')

index = []


index_result=['6000 index is list1']

def try_this(list1, index):
    for x, element in enumerate(list1):
        if element == 6000:
           index.append(x)
           index_result.append(index[:])
           index.pop()
        elif type(element) == list:
           index.append(x)
           try_this(element, index)
           index.pop()


print(try_this(list1, index))
print(index_result)
Sarah
  • 1
  • 2