Find value indices in 2d matrix

I have a view matrix

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

I want to get an index, say, for example, 9, which is at (2,2).

What I tried to do so far.

 for i,j in enumerate(mymatrix): for k,l in enumerate(j): if l==9: print i,k 

Is there a better way to do the same. Optimization, anyone? Thanks in advance.

+4
source share
5 answers

If you want all locations to be displayed in this value, you can use the following list comprehension with val set to whatever you are looking for

 [(index, row.index(val)) for index, row in enumerate(mymatrix) if val in row] 

eg:

 >>> mymatrix=[[1,2,9],[4,9,6],[7,8,9]] >>> val = 9 >>> [(index, row.index(val)) for index, row in enumerate(mymatrix) if val in row] [(0, 2), (1, 1), (2, 2)] 

EDIT

It is not true that this receives all occurrences, it will receive only the first occurrence of the value in a given string.

+6
source

If you convert mymatrix to a numpy array, you can use numpy.where to return the indices:

 >>> import numpy as np >>> mymatrix=[[1,2,3],[4,5,6],[7,8,9]] >>> a = np.array(mymatrix) >>> a array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> b = np.where(a==9) >>> b (array([2]), array([2])) >>> mymatrix=[[1,2,3],[9,5,6],[7,8,9]] >>> a = np.array(mymatrix) >>> a array([[1, 2, 3], [9, 5, 6], [7, 8, 9]]) >>> b = np.where(a==9) >>> b (array([1, 2]), array([0, 2])) 
+5
source

I think you can find the following useful, enlightening, and perhaps even surprising:

Edit: Moved the target value to the middle of the matrix to simulate an average location if the data is random and aligns the playing field for algorithms that stop as soon as they are found.

Timings were also performed for both Python 2 and comparison.

 from __future__ import print_function import sys import timeit setup = """ mymatrix=[[1,2,3],[4,9,6],[7,8,5]] # moved target value to middle val = 9 """ statements = { "Anuk (OP)": """ # finds all occurrences found = [] for i,j in enumerate(mymatrix): for k,l in enumerate(j): if l==val: found.append((i,k)) """, "Ryan Haining": """ # only finds first occurrence in each row found = [(index, row.index(val)) for index, row in enumerate(mymatrix) if val in row] """, "martineau": """ # finds all occurrences width = len(mymatrix[0]) found = [] posn = 0 for row in mymatrix: for col in row: if col == val: found.append((posn // width, posn % width)) posn += 1 """, "martineau #2": """ # finds all occurrences width = len(mymatrix[0]) found = [(posn // width, posn % width) for posn,elem in enumerate(col for row in mymatrix for col in row) if elem == val] """, "mtahmed": """ # stops after it finds first occurrence matrix_dim = len(mymatrix[0]) item_index = 0 for row in mymatrix: for i in row: if i == val: break item_index += 1 if i == val: break found = [(int(item_index / matrix_dim), item_index % matrix_dim)] """, } N = 1000000 R = 3 timings = [ (idea, min(timeit.repeat(statements[idea], setup=setup, repeat=R, number=N)), ) for idea in statements] longest = max(len(t[0]) for t in timings) # length of longest name print('fastest to slowest timings (Python {}.{}.{})\n'.format(*sys.version_info[:3]), ' ({:,d} executions, best of {:d})\n'.format(N, R)) ranked = sorted(timings, key=lambda t: t[1]) # sort by speed (fastest first) for timing in ranked: print("{:>{width}} : {:.6f} secs, rel speed {rel:>8.6f}x".format( timing[0], timing[1], rel=timing[1]/ranked[0][1], width=longest)) 

Output Example:

 fastest to slowest timings (Python 2.7.5) (1,000,000 executions, best of 3) mtahmed : 2.850508 secs, rel speed 1.000000x martineau : 3.684153 secs, rel speed 1.292455x Ryan Haining : 8.391357 secs, rel speed 2.943811x Anuk (OP) : 14.014551 secs, rel speed 4.916510x martineau #2 : 15.880949 secs, rel speed 5.571270x fastest to slowest timings (Python 3.3.2) (1,000,000 executions, best of 3) mtahmed : 5.019435 secs, rel speed 1.000000x martineau : 5.217747 secs, rel speed 1.039509x Ryan Haining : 5.705710 secs, rel speed 1.136723x Anuk (OP) : 8.317911 secs, rel speed 1.657141x martineau #2 : 11.590270 secs, rel speed 2.309078x 
+4
source

You can do this rather than using an enumeration. Not sure if this happens faster.

 matrix = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]] needle = 9 matrix_dim = len(matrix[0]) item_index = 0 for row in matrix: for i in row: if i == needle: break item_index += 1 if i == needle: break print(int(item_index / matrix_dim), item_index % matrix_dim) 

It takes exactly the time i * dim(matrix) + (j+1) , where the result is higher than ij , which may be O(n^2) in the worst case.

+2
source

if you want to find the index of the entire occurrence of val or a character in a 2d list, this code can help you and you can read it. TNQ.

 for i, e in enumerate(board): for j, ee in enumerate(e): if 'd' in ee: print(i, j) 

You can also find several occurrences.

0
source

Source: https://habr.com/ru/post/1488906/


All Articles