Python:查找两个数组之间*第一个*匹配项的索引

Python: Find indices of the *first* match between two arrays

我正在尝试比较从第 0 个索引开始的两个数组,以查找 arrayA 中的第一个 any 元素匹配 any 元素在 arrayB - 以及每个数组中的相应位置。

问题是,我编写的代码匹配匹配元素的 last 实例 - 我不太清楚为什么。

这是我的代码:

for a in arrayA:
     for b in arrayB:
          if a == b:
              indexA = arrayA.index(a)
              indexB = arrayB.index(b)

arrayA = ['j', 'e', 'b', 'a']arrayB = ['k', 'e', 'b', 'a']。代码 returns indexA = 3indexB = 3(在 'a' 上匹配),而我希望它为 return indexA = 1indexB = 1(匹配 'e')。

非常感谢任何建议!

您可以将其重构为一个函数(无论如何这都不是一个糟糕的主意),然后使用 return 立即跳出两个循环。

def firstMatch(arrayA, arrayB): for a in arrayA: for b in arrayB: if a == b: indexA = arrayA.index(a) indexB = arrayB.index(b) return (indexA, indexB)

或者,您可以将异常作为穷人的 goto 抛出。 Python 倾向于更容忍异常作为流程控制,但我不喜欢这个想法。

您还可以使用 "mismatched" if-else 子句来玩一个巧妙的技巧:

for a in arrayA: for b in arrayB: if a == b: indexA = arrayA.index(a) indexB = arrayB.index(b) break else: # NOT in-line with the if continue; break #in-line with the else.

最后,类似 C 的解决方案只是包含第二个 "guard" 变量,指示您是否找到了匹配项。

found = false; for a in arrayA: for b in arrayB: if a == b: indexA = arrayA.index(a) indexB = arrayB.index(b) found = true break if found: break

问题是一旦找到第一个匹配项,您就会继续循环。当您找到匹配项时,您需要 break 跳出循环。另外,您实际上不需要嵌套循环。

for a in arrayA:
    if a in arrayB:
        indexA = arrayA.index(a)
        indexB = arrayB.index(a)
        break

您应该使用 enumerate,它为每个元素的索引提供 set 用于 0(1) 查找,并且在找到时仅 break,每个 if a in arr_b是一个 0(n) 查找,而不是 0(1) 的集合,对于大数据会更有效:

st = set(arr_b)
for ind, a in enumerate(arr_a):
    if a in st:
        index_a = ind
        index_b = arr_b.index(a)
        break

让我建议 的性能改进。当您在请求它的索引之前不检查列表中对象的存在,而是在后者失败时处理异常时,您可以为自己节省一些(可能很多)比较。 N.B., 在 Python 中,请求宽恕 比请求许可更容易。

arrayA = [1,2,3,4,5,6,7,8]
arrayB = [8,7,6,5,4]

# assign default, just in case no match is found
indexB = None
for indexA, a in enumerate(arrayA):
    try:
        indexB = arrayB.index(a)
        break
    except ValueError:
        # item is not in list, continue search
        continue

print indexA, indexB, arrayA[indexA], arrayB[indexB]

请注意,使用集合数据结构可以有效地找出某个项目是否值得检索其索引,可以节省更多的比较。这实际上是 .

arrayA = [1,2,3,4,5,6,7,8]
arrayB = [8,7,6,5,4]

# assign default, just in case no match is found
indexB = None
setB = set(arrayB)
for indexA, a in enumerate(arrayA):
    if a in setB:
        indexB = arrayB.index(a)
        break

print indexA, indexB, arrayA[indexA], arrayB[indexB]

两种情况下的预期输出都是:

$ python test.py
3 4 4 4

第一个匹配项是 arrayA 中的索引 3 和 arrayB 中的索引 4,在这两种情况下都是 4.