Ab Python3
map
gibt nicht mehr a zurück, list
sondern a mapObject
, daher sieht die Antwort ungefähr so aus
>>> map(lambda x:x.strip(),l)
<map object at 0x7f00b1839fd0>
Sie können mehr darüber auf lesen Was ist neu in Python 3.0 .
map()
und filter()
Rückgabe von Iteratoren. Wenn Sie wirklich eine brauchen list
, ist eine schnelle Lösung zlist(map(...))
Wie kann man nun durchkommen?
Fall 1 - Der list
Anruf map
mit alambda
map
Gibt einen Iterator zurück . list
ist eine Funktion, die einen Iterator in eine Liste konvertieren kann. Daher müssen Sie einen list
Anruf abschließen map
. Die Antwort lautet nun:
>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> list(map(lambda x:x.strip(),l))
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Sehr gut, wir bekommen die Ausgabe. Jetzt überprüfen wir, wie lange es dauert, bis dieser Code ausgeführt wird.
$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];list(map(lambda x:x.strip(),l))"
100000 loops, best of 3: 2.22 usec per loop
2,22 Mikrosekunden. Das ist nicht so schlimm Aber gibt es effizientere Wege?
Fall 2 - Der list
Anruf map
ohne alambda
lambda
wird von vielen in der Python-Community (einschließlich Guido ) missbilligt . Abgesehen davon wird die Geschwindigkeit des Programms erheblich reduziert. Daher müssen wir dies so weit wie möglich vermeiden. Die Toplevel-Funktion str.strip
. Kommt uns hier zu Hilfe.
Das map
kann ohne Verwendung lambda
von str.strip
as neu geschrieben werden
>>> list(map(str.strip,l))
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Und jetzt zu den Zeiten.
$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];list(map(str.strip,l))"
1000000 loops, best of 3: 1.38 usec per loop
Fantastisch. Sie können die Effizienzunterschiede zwischen den beiden Möglichkeiten erkennen. Es ist fast 60% schneller. Daher ist der Ansatz ohne Verwendung von a lambda
hier eine bessere Wahl.
Fall 3 - Befolgen Sie die Richtlinien, den regulären Weg
Ein weiterer wichtiger Punkt von Was ist neu in Python 3.0? Es wird empfohlen, dies nach Möglichkeit zu vermeiden map
.
Besonders knifflig wird map()
für die Nebenwirkungen der Funktion aufgerufen; Die richtige Transformation besteht darin, eine reguläre for
Schleife zu verwenden (da das Erstellen einer Liste nur verschwenderisch wäre).
So können wir dieses Problem ohne map
eine reguläre for
Schleife lösen .
Die triviale Art der Lösung (die Brute-Force) wäre:
>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> final_list = []
>>> for i in l:
... final_list.append(i.strip())
...
>>> final_list
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Das Timing-Setup
def f():
l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
final_list = []
for i in l:
final_list.append(i.strip())
import timeit
print(min(timeit.repeat("f()","from __main__ import f")))
Und das Ergebnis.
1.5322505849981098
Wie Sie sehen, ist die Brute-Force hier etwas langsamer. Für einen normalen Programmierer ist es jedoch definitiv besser lesbar als eine map
Klausel.
Fall 4 - Listenverständnisse
Ein Listenverständnis ist hier ebenfalls möglich und entspricht dem in Python2.
>>> [i.strip() for i in l]
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Nun zu den Timings:
$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];[i.strip() for i in l]"
1000000 loops, best of 3: 1.28 usec per loop
Wie Sie sehen, ist das Listenverständnis effektiver als map
(auch das ohne a lambda
). Daher lautet die Daumenregel in Python3, stattdessen ein Listenverständnis zu verwendenmap
Fall 5 - In-Place-Mechanismen und Raumeffizienz ( TMT )
Eine letzte Möglichkeit besteht darin, die Änderungen in der Liste selbst vorzunehmen. Dies spart viel Speicherplatz. Dies kann mit erfolgen enumerate
.
>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> for i,s in enumerate(l):
... l[i] = s.strip()
...
>>> l
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Das Timing-Ergebnis wäre 1.4806894720022683
. Dieser Weg ist jedoch platzsparend.
Fazit
Eine vergleichende Liste von Timings (sowohl Python 3.4.3 als auch Python 3.5.0)
----------------------------------------------------
|Case| method | Py3.4 |Place| Py3.5 |Place|
|----|-----------------|-------|-----|-------|-----|
| 1 | map with lambda | 2.22u | 5 | 2.85u | 5 |
| 2 | map w/o lambda | 1.38u | 2 | 2.00u | 2 |
| 3 | brute-force | 1.53u | 4 | 2.22u | 4 |
| 4 | list comp | 1.28u | 1 | 1.25u | 1 |
| 5 | in-place | 1.48u | 3 | 2.14u | 3 |
----------------------------------------------------
Beachten Sie schließlich, dass das Listenverständnis der beste und die map
Verwendung lambda
der schlechteste ist. Aber nochmal --- NUR IN PYTHON3