2014-12-17 16 views
6

In der Dokumentation von defaultdict gibt es dieses Beispiel:Wie ist Python itertools `constant_factory` Beispiel besser als` Lambda: x`?

>>> def constant_factory(value): 
...  return itertools.repeat(value).next 

als „Eine schnellen und flexiblere Weise konstante Funktionen zu schaffen“.

Wie ist das überlegen

def constant_factory(value): 
    return lambda : value 

?

Beachten Sie, dass natürlich niemand eine Funktion dafür definieren würde ... nur mit (lambda: 42) ist klarer und kürzer zu tippen als constant_factory(42) aufrufen.

Für eine konstante Fabrik Schaffung eines wandelbaren Rückkehr, wenn das gesucht ein (lambda x=[]:x) verwenden könnte (btw das ist, was constant_factory([]) tun würde, aber es ist etwas, das oft zurück beißt ... siehe zum Beispiel this question).

+0

Vielleicht ist die Itertools-Implementierung optimiert und schneller als ein allgemeines Lambda? –

Antwort

4

itertools.repeat(value).next Erstaunlicherweise ist eigentlich etwa 30% zwei bis drei Mal schneller sowohl Python 2 und Python 3 (mit der offensichtlichen Variation __next__).

Es ist nicht viel aber auch gibt es keinen Grund, es zu verschwenden.

PS: Ich würde sagen, dass dies zeigt, dass lambda verbessert werden könnte (ich eine gebundene Methode dafür, dass schneller als ein Verschluss keinen logischen Grund sehen), aber lambda ist nicht wirklich in der Python-Community geliebt.

Der Grund dafür ist, dass itertools Grundelemente in C implementiert sind, während ein Lambda Python-Bytecode ausführt. Einen Capture-Wert einfach zurückzugeben ist sehr schnell, aber es ist immer noch Bytecode und erfordert eine Menge Setup/Teardown wie jeder Python-Funktionsaufruf.

+1

Es ist nicht so, dass "Lambda" langsamer als "itertools.repeat" ist, es ist, dass Python-Funktionen langsamer als C-Funktionen sind. Wenn Sie den Bytecode und die Typen der Funktionen überprüfen, werden Sie sehen, dass das "Lambda" genau entspricht "def (): Rückgabewert". Die Tatsache, dass "Wert" eine Schließvariable ist, kann ebenfalls ins Spiel kommen, aber ein hartcodiertes "Lamda: 42" nimmt in meinen Messungen bereits 1,77 x so lange wie "Wiederholung" an. – delnan