9

我有一个表格的矩阵,

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

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

4

5 回答 5

12

如果您将 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]))
于 2013-06-30T09:21:43.540 回答
10

如果您想要该值出现的所有位置,您可以使用以下列表推导并将其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)]

编辑

这并不是真的得到所有的出现,它只会得到给定行中第一次出现的值。

于 2013-06-29T22:57:20.317 回答
5

这是迄今为止发布的所有答案的基准,包括我自己的两个。我认为您可能会发现结果很有用、很有启发性,甚至可能令人惊讶。;¬)

请注意,如果数据是随机的,我已将目标值放在矩阵的中间以模拟其平均位置,以便为一旦发现就停止的算法(一点点)提供公平的竞争环境——比较仍然没有然而,这真的很公平。

在 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

于 2013-06-30T03:11:50.437 回答
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)最坏的情况。

于 2013-06-30T00:37:43.353 回答
0

如果您想在 2d 列表中查找所有出现的 val 或字符的索引,此代码可能会帮助您并且它是可读的。Tnq。

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

您也可以找到多次出现。

于 2017-10-01T07:12:23.047 回答