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 = 3
和 indexB = 3
(在 'a' 上匹配),而我希望它为 return indexA = 1
和 indexB = 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
.
我正在尝试比较从第 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 = 3
和 indexB = 3
(在 'a' 上匹配),而我希望它为 return indexA = 1
和 indexB = 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
让我建议
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
.