【问题标题】:Python: Find fast match in 2 lists (Collision)Python:在 2 个列表中查找快速匹配(碰撞)
【发布时间】:2014-12-23 12:34:22
【问题描述】:

我在 python 中遇到了效率问题。 几天来,我一直在尝试寻找和测试不同的实现,但无法让它足够快地工作。

任务:我有两个列表 arr 和 arr2,其中包含 1000000 个 b'' 条目(使用密钥“00000000”到“00999999”进行加密和解密) 并且知道必须在这两个中找到匹配项(DES2 在中间相遇)。因此

if arr[x] == arr2[y]:
    return x, y

我认为我的解决方案会奏效,但速度太慢,还不够:

def g(x):
    for k in range(0, 1000000):
        if (arr[x] == arr2[k]):
            return k, x
    return 0

keypair = 0

for k in range(0, 1000000):
    if keypair == 0:
        keypair = g(k)
    else:
        break

问题是,密钥对应该在 40 秒内找到,但是例如对于 1000000 个条目中的 1000 个条目,此示例需要 1 分钟。

现在必须以某种方式提高效率。我尝试了一些其他解决方案,这些解决方案承诺更高的效率,例如数组的 map 和 numpys 解决方案,但在速度上没有得到任何真正的提高。

您知道任何智能解决方案吗?

【问题讨论】:

  • Python 相当慢,尤其是在紧密的循环中。如果 pypy 不起作用,则在 c (cython) 中对其进行编码。
  • 为什么有两个循环?正如 simonzack 所说,cython 将显着提高性能。
  • 这段来自 scipy 2013 的视频将告诉你该怎么做youtube.com/watch?v=KJFaJoJCqlU
  • 您可以使用并行处理。创建进程池。每个进程都在 g() 上运行。打破范围(1000000)。给每个进程范围,x。您可以在
  • 您是否尝试过使用sorted(enumerate(a), key = lambda x: x[1]) 之类的方式对列表进行排序以保留原始索引?

标签: python performance list match


【解决方案1】:

我不确定您是只对存在感兴趣还是需要列表中的索引。该解决方案与索引案例有关。如果您只需要检查是否存在,只需使用g 作为set 而不是字典,并检查k 是否在g 中,对于k 中的每个k

如果空间不是问题,请尝试字典:

g = {k:i for i,k in enumerate(arr)}

keypair = None
for i,k in enumerate(arr2):
    if k in g:
        keypair = (i, g[k])
        break;

哈希表在查找操作上摊销 O(1)。

无论如何,用 cython 编写并不难(即使使用本机类型),但如果您不更改算法并仍然使用 O(n^2) 方法,您的目标将失败。

这种方法是 O(n),但会使用大量内存,并且可能使用高常数。您的问题的维度 (n=1000000) 应该是最好的,但可能对数组值进行排序,然后考虑到它们的排序可以更快,即使是 O(nlog(n)) 方法。如果第一次失败,您可以尝试通过排序数据。

【讨论】:

  • 词典速度非常快,正是解决了我的问题的原因。谢谢。
猜你喜欢
  • 1970-01-01
  • 2022-11-17
  • 2020-11-23
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-31
  • 1970-01-01
相关资源
最近更新 更多