我有一个表格的矩阵,
mymatrix=[[1,2,3],[4,5,6],[7,8,9]]
我想获取例如(2,2)处的 9 的索引。
到目前为止我一直在尝试做的事情。
for i,j in enumerate(mymatrix):
for k,l in enumerate(j):
if l==9:
print i,k
有没有更好的方法来做同样的事情。优化,有人吗?提前致谢。
我有一个表格的矩阵,
mymatrix=[[1,2,3],[4,5,6],[7,8,9]]
我想获取例如(2,2)处的 9 的索引。
到目前为止我一直在尝试做的事情。
for i,j in enumerate(mymatrix):
for k,l in enumerate(j):
if l==9:
print i,k
有没有更好的方法来做同样的事情。优化,有人吗?提前致谢。
如果您将 mymatrix 转换为 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]))
如果您想要该值出现的所有位置,您可以使用以下列表推导并将其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)]
编辑
这并不是真的得到所有的出现,它只会得到给定行中第一次出现的值。
这是迄今为止发布的所有答案的基准,包括我自己的两个。我认为您可能会发现结果很有用、很有启发性,甚至可能令人惊讶。;¬)
请注意,如果数据是随机的,我已将目标值放在矩阵的中间以模拟其平均位置,以便为一旦发现就停止的算法(一点点)提供公平的竞争环境——比较仍然没有然而,这真的很公平。
在 Python 2 和 3 下运行。
更新- 添加了上次更新后发布的答案。
from __future__ import print_function
import numpy as np
import sys
from textwrap import dedent
import timeit
EXECUTIONS = 1000000 # Number of times each algorithm is executed per timing run.
TIMINGS = 3 # Number of timing runs.
SETUP = dedent("""
# Make accessible in algorithms.
from __main__ import np
mymatrix=[[1,2,3], [4,9,6], [7,8,5]] # Target value in middle.
val = 9 # Target value.
""")
algorithms = {
"user2459905 (OP) - all occurrences": dedent("""
# finds all occurrences
found = []
for i,j in enumerate(mymatrix):
for k,l in enumerate(j):
if l==val:
found.append((i,k))
"""),
"ayush thakur (fixed) - all occurrences": dedent("""
# finds all occurrences
found = []
for i, e in enumerate(mymatrix):
for j, ee in enumerate(e):
if val == ee: # Fixed.
found.append((i, j))
"""),
"martineau #1 - all occurrences": dedent("""
# finds all occurrences
width = len(mymatrix[0])
found = []
posn = 0
for row in mymatrix:
if val not in row:
posn += width
else:
for col in row:
if col == val:
found.append((posn // width, posn % width))
posn += 1
"""),
"martineau #2 - all occurrences": dedent("""
# finds all occurrences
width = len(mymatrix[0])
found = []
posn = 0
for row in mymatrix:
if val in row:
for y,col in enumerate(row):
if col == val:
found.append((posn // width, y))
posn += width
"""),
"mmtauqir - first occurrence": dedent("""
# finds all occurrences
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)
"""),
"rtrwalker - all occurrences using numpy": dedent("""
# finds all occurrences using numpy
a = np.array(mymatrix) # Convert mymatrix to a numpy array.
found = np.where(a==val)
"""),
"Ryan Haining - first occurrence (per row)": dedent("""
# finds first occurrence in each row
found = [(index, row.index(val)) for index, row in enumerate(mymatrix)
if val in row]
"""),
}
# Benchmark algorithms
timings = [
(label, min(timeit.repeat(algorithms[label], setup=SETUP,
repeat=TIMINGS, number=EXECUTIONS)))
for label in algorithms
]
# Display metrics.
longest = max(len(timing[0]) for timing in timings) # Length of longest label.
print('Fastest to slowest execution speeds with {}-bit Python {}.{}.{}'.format(
64 if sys.maxsize > 2**32 else 32, *sys.version_info[:3]))
print(' with numpy version {}'.format(np.version.full_version),
'-> {:,d} executions, best of {:,d})'.format(EXECUTIONS, TIMINGS))
print()
ranked = sorted(timings, key=lambda t: t[1]) # sort by speed (fastest first)
for timing in ranked:
print("{:>{width}} : {:.6f} secs, rel speed {rel:6.3f}x".format(
timing[0], timing[1], rel=timing[1]/ranked[0][1], width=longest))
结果:
Fastest to slowest execution speeds with 32-bit Python 2.7.18
with numpy version 1.16.6 -> 1,000,000 executions, best of 3)
mmtauqir - first occurrence : 0.667560 secs, rel speed 1.000x
Ryan Haining - first occurrence (per row) : 0.694786 secs, rel speed 1.041x
martineau #1 - all occurrences : 0.752011 secs, rel speed 1.127x
martineau #2 - all occurrences : 0.929674 secs, rel speed 1.393x
ayush thakur (fixed) - all occurrences : 1.541785 secs, rel speed 2.310x
user2459905 (OP) - all occurrences : 1.544341 secs, rel speed 2.313x
rtrwalker - all occurrences using numpy : 3.334727 secs, rel speed 4.995x
Fastest to slowest execution speeds with 32-bit Python 3.8.8
with numpy version 1.21.1 -> 1,000,000 executions, best of 3)
mmtauqir - first occurrence : 0.734707 secs, rel speed 1.000x
Ryan Haining - first occurrence (per row) : 0.749999 secs, rel speed 1.021x
martineau #2 - all occurrences : 0.820354 secs, rel speed 1.117x
martineau #1 - all occurrences : 0.880883 secs, rel speed 1.199x
user2459905 (OP) - all occurrences : 1.436644 secs, rel speed 1.955x
ayush thakur (fixed) - all occurrences : 1.638413 secs, rel speed 2.230x
rtrwalker - all occurrences using numpy : 5.713464 secs, rel speed 7.777x
您可以这样做而不是使用枚举。完全不确定这是否更快。
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)
最坏的情况。
如果您想在 2d 列表中查找所有出现的 val 或字符的索引,此代码可能会帮助您并且它是可读的。Tnq。
for i, e in enumerate(board):
for j, ee in enumerate(e):
if 'd' in ee:
print(i, j)
您也可以找到多次出现。