【问题标题】:Way to optimise Python nested list loops优化 Python 嵌套列表循环的方法
【发布时间】:2015-08-15 15:11:33
【问题描述】:

我目前正在 Python 3 中处理这个函数:

def BToBInter(Array):
    NewA = []
    Amount = 23
    Res = 0
    M = len(Array) - 24
    for P in range(M):
        for I in Array[P:P+24]:
            if I == 1:
                Res += (1 << Amount)
            Amount -= 1
        NewA.append(Res)
        Amount = 23
        Res = 0
    return NewA

想法是:

  • 输入“数组”是一个 Python 位列表(1 和 0);
  • 首先,读取列表的第 0 到 23 位,转换为整数并添加到列表“NewA”中;
  • 然后读取位 1 到 24,然后读取 2 到 25、3 到 26 等等。

因此,N 位的位列表会产生 N-24 个整数的整数列表。

这对于大型位列表运行相当缓慢。 Cython 有帮助,但我觉得代码可以更有效地开始。我经常使用列表推导,但我不确定如何将它们应用于这些嵌套循环。有什么建议吗?

【问题讨论】:

  • 看起来你正在实现一个移动窗口;您可以使用itertools 来执行此操作,请参见例如github.com/mahmoud/boltons/blob/master/boltons/…
  • 阵列有多大?你需要算法有多快?顺便说一句,请不要对变量和函数使用大写的名称……这些名称是用于类的,只会引起混淆。

标签: python list loops nested bits


【解决方案1】:

没有时间检查是否所有边缘情况都得到了正确处理,但这里有一个想法。现在,每个窗口(可能)有 24 个班次和总和。但是,当您已经获得了一个窗口的值时,可以计算该窗口移位 1 的值,而无需遍历整个 24:您所需要做的就是减去由于元素掉出而导致的组件窗户;将其乘以 2;并添加组件,因为新元素已进入窗口。具体来说:

def new_bit(arr, window_size):
    start = sum(1 << (window_size-i-1) for i in range(window_size) if arr[i])
    results = [start]
    maxpow = 1 << (window_size-1)
    for j in range(window_size, len(arr)-1):
        last = results[-1]
        common = last - arr[j-window_size] * maxpow
        new = common * 2 + arr[j]
        results.append(new)
    return results

这给了我

>>> w = [random.randint(0,1) for i in range(30)]
>>> BToBInter(w)
[7981231, 15962463, 15147711, 13518207, 10259198, 3741180]
>>> new_bit(w,24)
[7981231, 15962463, 15147711, 13518207, 10259198, 3741180]
>>> %timeit BToBInter(w)
10000 loops, best of 3: 37.5 µs per loop
>>> %timeit new_bit(w, 24)
100000 loops, best of 3: 13.5 µs per loop
>>> w = [random.randint(0,1) for i in range(10**6)]
>>> %timeit BToBInter(w)
1 loops, best of 3: 5.56 s per loop
>>> %timeit new_bit(w, 24)
1 loops, best of 3: 771 ms per loop

正如我所说,实施中可能存在错误。但是通过尽可能多地重用上一步的计算来加速滑动窗口计算的基本思想是合理的,并且非常普遍。

【讨论】:

  • 好主意! common = last &amp; ((1&lt;&lt;window_size-1)-1) 怎么样,或者甚至可以提前保存这个面具。
  • DSM,当我在我的程序中使用时,您的方法缩短了几秒钟。 jonrsharpe,我会研究一下 Itertools,看看我能用它们做什么。尽管 cmets 框推荐了,我还是要感谢你们俩。
猜你喜欢
  • 2017-05-28
  • 2019-05-29
  • 2021-01-21
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多