Python: Zählt Python Lists für len () oder zählt es für jeden Aufruf?

79

Wenn ich len () auf einer sehr langen Liste immer wieder aufrufe, verschwende ich Zeit oder bleibt eine int-Zählung im Hintergrund?

PKKid
quelle
Das hat mich immer nervt. Besonders als mir mein Profiler sagte, dass ich 2,2 Sekunden eines Programms verbracht habe, das eine Minute lang ausgeführt wurde, um diese Funktion aufzurufen.
Nathan

Antworten:

87

Keine Sorge: Natürlich spart es die Zählung und ist daher len()auf Listen eine ziemlich billige Operation. Gleiches gilt übrigens für Strings, Wörterbücher und Sets!

Ferdinand Beyer
quelle
Ich glaube, es behält eine Zählung wie den Index des letzten Elements + 1 oder so und ruft den Wert von len () von diesem Speicherort auf. Habe ich recht?
Geekidharsh
13

Schreiben Sie Ihr Programm so, dass es für Klarheit optimiert und leicht zu warten ist . Ist Ihr Programm mit einem Aufruf an klarer len(foo)? Dann mach das.

Sind Sie besorgt über die benötigte Zeit? Verwenden Sie das timeitModul in der Standardbibliothek , um die benötigte Zeit zu messen und festzustellen, ob sie in Ihrem Code von Bedeutung ist.

Sie werden, wie die meisten Leute, sehr wahrscheinlich falsch raten, welche Teile Ihres Programms am langsamsten sind. Vermeiden Sie die Versuchung zu raten und messen Sie sie stattdessen, um es herauszufinden.

Denken Sie daran, dass vorzeitige Optimierung nach Donald Knuths Worten die Wurzel allen Übels ist. Konzentrieren Sie sich nur auf die Geschwindigkeit des Codes, dessen Geschwindigkeit Sie gemessen haben , um festzustellen, ob der Nutzen die Kosten für eine Änderung der Funktionsweise wert ist.

große Nase
quelle
1
Ich bin nur wenige Monate nach meiner Arbeit ein Programmierer und unterstütze beide Praktiken. Das Timer-Zeug bietet eine zweizeilige Verteidigung gegen eine große Menge konventioneller Weisheit ("SELECT .. RANDOM is too teuer"), die auf Ihre Weise geschleudert wird.
Jesvin Jose
5

Die Frage wurde beantwortet ( lenist O (1)), aber so können Sie es selbst überprüfen:

$ python -m timeit -s "l = range(10)" "len(l)"
10000000 loops, best of 3: 0.119 usec per loop
$ python -m timeit -s "l = range(1000000)" "len(l)"
10000000 loops, best of 3: 0.131 usec per loop

Ja, nicht wirklich langsamer.

dF.
quelle
3

Eine Python "Liste" ist wirklich ein anpassbares Array, keine verknüpfte Liste, daher speichert sie die Größe irgendwo.

Ken
quelle
0

Die Länge muss irgendwo gespeichert werden, damit Sie nicht jedes Mal die Anzahl der Elemente zählen.

Georg Schölly
quelle
4
Seien Sie gewarnt, dies gilt nicht unbedingt für jede Sprache. Einige Sprachen verwenden tatsächlich eine verknüpfte Liste und können Metadaten über die Größe beibehalten oder nicht. Ein perfektes Beispiel ist Lisp, wo Listen relativ primitive 2-Zell-Strukturen verwenden, um sich selbst aufzubauen, keine Metadaten. In diesen Fällen benötigt ein Längenaufruf O (n) Zeit.
Ashton K