5

Pythonで配列の前部を拡張する最速の方法は何ですか? a と b の 2 つの配列があるとします。a = b+a (b は変わらないはず) の最速の方法を作りたいです。

私の小さなベンチマーク:

テスト 1:

a,b = [],[]
for i in range(0,100000):
    a.append(i)
    b.append(i)

def f(a,b):
    for i in range(0,100):
        a=a+b

import cProfile
cProfile.run('f(a,b)')

時間: ~12 秒

テスト 2:

a,b = [],[]
for i in range(0,100000):
    a.append(i)
    b.append(i)

def f(a,b):
    for i in range(0,100):
        a[0:0] = b

import cProfile
cProfile.run('f(a,b)')

時間: ~1.5 秒

テスト3:

a,b = [],[]
for i in range(0,100000):
    a.append(i)
    b.append(i)

lenb = len(b)
def f(a,b):
    for i in range(0,100):
        b.extend(a)
        # do something with b
        b = b[:lenb]

import cProfile
cProfile.run('f(a,b)')

時間: ~0.4 秒

しかし、リストの連結はいくつかの基になるポインターの変更として行う必要があるため、より高速になるはずだと思います。そして、次のコードは最速のものですが、a ではなく b を変更します (したがって、私たちの目的には適していません): test "WRONG":

a,b = [],[]
for i in range(0,100000):
    a.append(i)
    b.append(i)

def f(a,b):
    for i in range(0,100):
        b.extend(a)

import cProfile
cProfile.run('f(a,b)')

時間: ~0.13 秒

したがって、理論的には、テスト「間違った」時間の前に拡張する方法があるはずです。

4

1 に答える 1

10

絶対的な最速の方法はcollections.deque、まさにこの用途に最適化され、呼び出されたメソッドを持ち.appendleft.extendleftコードを読みやすくするためにを使用することです-appendleft缶に書かれていることを正確に実行します(つまり、両端キューの左側に追加されます) 、およびextendleft同等の機能を実行します。

def extendleft(self, other)
    for item in other:
        self.appendleft(c)

したがって、a = b+aスペルは次のようになります。

a.extendleft(reversed(b))
于 2012-06-21T09:06:55.343 に答える