【问题标题】:How do I make this matching list code more efficient?如何使此匹配列表代码更有效?
【发布时间】:2020-04-10 04:42:08
【问题描述】:

我有两个列表。我想获得匹配的索引。我想出了下面的例子来说明:

a = [1,2,6,5,3,4]
b = [1,3,4,2,5,6]

for i in range(len(a)):
    for j in range(len(b)):
        if b[j] != a[i]:
            next
        else:
            print(i, j)    

看起来相当简单,但有点长。谁能帮我提高这段代码的效率?

输出:

0 0
1 3
2 5
3 4
4 1
5 2

【问题讨论】:

  • 这将有助于添加输出
  • 所需的输出为:[[0,0], [1,3], [2,5],[3,4],[4,1],[5,2]]。目前,它只打印匹配的索引。
  • 是的,我的意思是当前输出。反正我给你加了。
  • 你说得不够具体:P哈哈谢谢!

标签: python-3.x list matching


【解决方案1】:
a = [1,2,6,5,3,4]
b = [1,3,4,2,5,6,1,2,3,4,5,6]

b_dict = {}
for i, n in enumerate(b):
    if n not in b_dict:
        b_dict[n] = []
    b_dict[n].append(i)

for i in range(len(a)):
    if a[i] in b_dict:
        for index in b_dict[a[i]]:
            print(i, index)

O(a+b) 解决方案,因为字典中的“in”是 O(1)

更新版本允许匹配 b 中的重复数字

【讨论】:

  • 嗨,好方法!您可以将第一个循环替换为b_dict = dict(enumerate(b))
  • 您可以使用enumerate 简化第二个循环,类似于@game0ver 和我的答案,即for i, m in enumerate(a): if m in b: print(i, b[m])
  • 我在应用它时意识到了其他一些事情。您只能使用 b 的一个实例。所以你不能将 a 中的多个元素匹配到一个 b。
【解决方案2】:

你可以像这样使用列表推导:

>>> a = [1,2,6,5,3,4]
>>> b = [1,3,4,2,5,6]
>>>
>>> [[i,j] for i,k in enumerate(a) for j,v in enumerate(b) if k==v]
[[0, 0], [1, 3], [2, 5], [3, 4], [4, 1], [5, 2]]

【讨论】:

  • 太棒了。谢谢!
【解决方案3】:

提示

  1. 如果您有一个使用索引及其各自值的循环,请使用enumerate 而不是range(len()) 和索引。
  2. 在这种情况下,您无需担心不匹配的条件 (if b[j] != a[i])。
>>> for i, v0 in enumerate(a):
...     for j, v1 in enumerate(b):
...         if v0 == v1:
...             print(i, j)
... 
0 0
1 3
2 5
3 4
4 1
5 2

作为列表理解:

>>> [(i, j) for i, v0 in enumerate(a) for j, v1 in enumerate(b) if v0 == v1]
[(0, 0), (1, 3), (2, 5), (3, 4), (4, 1), (5, 2)]

(我输出了元组,因为它们在这种情况下似乎更有意义。)

【讨论】:

    猜你喜欢
    • 2014-05-03
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多