我有一个表格矩阵,
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
有没有更好的方法来做同样的事情。优化,任何人?提前谢谢。
答案 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)
你也可以找到多个事件。