在2d矩阵中查找值的索引

时间:2013-06-29 22:51:03

标签: python optimization matrix

我有一个表格矩阵,

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

我想得到索引,比如9,它是(2,2)。

到目前为止我试图做的事情。

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

有没有更好的方法来做同样的事情。优化,任何人?提前谢谢。

5 个答案:

答案 0 :(得分:7)

如果您想要显示该值的所有位置,您可以使用以下列表理解,val设置为您要搜索的内容

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

例如:

>>> 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)]

修改

这并不是真的,这一切都会发生,它只会在给定的行中首次出现该值。

答案 1 :(得分:6)

如果将矩阵转换为numpy数组,则可以使用numpy.where返回索引:

>>> 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]))

答案 2 :(得分:4)

我认为您可能会发现以下有用,有启发性,甚至可能令人惊讶的事情:

编辑:如果数据是随机的,则将目标值移动到矩阵的中间以模拟平均位置,并为找到的算法立即停止算法的游戏区域。

同时在Python 2& 3用于比较。

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))

示例输出:

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

答案 3 :(得分:2)

你可以这样做而不是使用枚举。不确定这是否更快。

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)

这将花费时间i * dim(matrix) + (j+1),其中上述结果为i j,在最坏的情况下可能为O(n^2)

答案 4 :(得分:0)

如果你想在2d列表中找到所有val或字符出现的索引,这段代码可以帮助你,它是可读的。 TNQ。

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

你也可以找到多个事件。