Int () -Funktion für jedes Listenelement aufrufen?

183

Ich habe eine Liste mit numerischen Zeichenfolgen, wie folgt:

numbers = ['1', '5', '10', '8'];

Ich möchte jedes Listenelement in eine Ganzzahl konvertieren, damit es so aussieht:

numbers = [1, 5, 10, 8];

Ich könnte es mit einer Schleife machen, wie folgt:

new_numbers = [];
for n in numbers:
    new_numbers.append(int(n));
numbers = new_numbers;

Muss es so hässlich sein? Ich bin sicher, es gibt eine pythonischere Möglichkeit, dies in einer Codezeile zu tun. Bitte hilf mir.

Silbernes Licht
quelle
1
Welche Version von Python verwenden Sie?
Mark Byers

Antworten:

131

In Python 2.x besteht ein anderer Ansatz darin, Folgendes zu verwenden map:

numbers = map(int, numbers)

Hinweis: In Python 3.x wird mapein Kartenobjekt zurückgegeben, das Sie bei Bedarf in eine Liste konvertieren können:

numbers = list(map(int, numbers))
Mark Byers
quelle
11
Gibt in Python 3.x mapeinen Iterator anstelle einer Liste zurück, sodass er so geschrieben werden muss, als list(map(int, numbers))ob eine Liste benötigt wird.
Kennytm
2
Ich denke, derzeit ist der Ansatz des Listenverständnisses etwas bevorzugter.
Extraneon
3
@extraneon: Ja ... oder vielleicht sollten Sie einen Generator anstelle einer Liste verwenden, je nachdem, wofür Sie ihn verwenden. Der Vorteil eines Generators besteht darin, dass Sie keine Zeit damit verschwenden müssen, sie im Voraus zu berechnen, wenn Sie möglicherweise nicht alle Elemente betrachten müssen.
Mark Byers
4
Gemessen mit Zeit unter Python 2.7.2: LC: 3.578153133392334, Karte: 4.9065070152282715
AJJ
1
@AJJ: maphat einen höheren Einrichtungsaufwand, aber auf dem Referenzinterpreter hat die Transformationsfunktion, wenn es sich um eine in C implementierte Python-Funktion handelt, niedrigere Kosten pro Element. Das Testen mit einer Eingabe von nur vier Werten liefert keine nützlichen Informationen zur Skalierung. Das heißt, in meinen eigenen Tests (auf Py2.7.12 und Py3.5.2, letzteres mit list()Wrapping) hat Py2 mapsogar für vier Elementeingaben gewonnen und auf Py3 nur einen winzigen Vorsprung verloren; Ich vermute, Ihre Tests wurden zugunsten von Listcomps verzerrt.
ShadowRanger
21

nur ein Punkt,

numbers = [int(x) for x in numbers]

Das Listenverständnis ist dabei natürlicher

numbers = map(int, numbers)

ist schneller.

Wahrscheinlich spielt dies in den meisten Fällen keine Rolle

Nützliche Lektüre: LP vs Karte

renatopp
quelle
6
Sollte es nicht number = map (int, number) sein?
Karan
9

Wenn Sie diese Ganzzahlen an eine Funktion oder Methode übergeben möchten, betrachten Sie dieses Beispiel:

sum(int(x) for x in numbers)

Diese Konstruktion ist absichtlich bemerkenswert ähnlich den von Adamk erwähnten Listenverständnissen. Ohne die eckigen Klammern wird es als Generatorausdruck bezeichnet und ist eine sehr speichereffiziente Methode, um eine Liste von Argumenten an eine Methode zu übergeben. Eine gute Diskussion finden Sie hier: Generatorausdrücke vs. Listenverständnis

Tim McNamara
quelle
4

Eine andere Möglichkeit, es in Python 3 zu schaffen:

numbers = [*map(int, numbers)]

zhukovgreen
quelle
1
Kannst du das erklären? Ich bin mit dieser Syntax nicht vertraut. Vielen Dank!
Abalter
1
Ich verwende das Auspacken der Argumentliste ( docs.python.org/3/tutorial/… )
zhukovgreen
Aha, eine Python 3 Sache. Scheint seltsam [], eine Argumentliste genommen zu haben . Und ich wusste nicht, dass Sie einen Iterator als Argumentliste übergeben können. Ich hätte gedacht zu tun number = list(map(int, numbers)). Aber danke für die Erklärung!
Abalter
3

Ein anderer Weg,

for i, v in enumerate(numbers): numbers[i] = int(v)
Nick Dandoulakis
quelle
6
OP sagte Python
SilentGhost
3
Diese Methode ist sehr nützlich, wenn Sie die Operation nur für einige der Elemente in der Liste ausführen möchten. Dies ist nicht relevant für die Frage in diesem Thread, aber es kann Fälle geben, in denen es hilfreich ist
Dikla
1

Ich dachte, ich würde die Antworten konsolidieren und einige timeitErgebnisse zeigen .

Python 2 ist ziemlich schlecht darin, aber es mapist ein bisschen schneller als das Verstehen.

Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> setup = """import random
random.seed(10)
l = [str(random.randint(0, 99)) for i in range(100)]"""
>>> timeit.timeit('[int(v) for v in l]', setup)
116.25092001434314
>>> timeit.timeit('map(int, l)', setup)
106.66044823117454

Python 3 ist an sich mehr als viermal schneller, aber das Konvertieren des mapGeneratorobjekts in eine Liste ist immer noch schneller als das Verstehen, und das Erstellen der Liste durch Entpacken des mapGenerators (danke Artem!) Ist noch etwas schneller.

Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> setup = """import random
random.seed(10)
l = [str(random.randint(0, 99)) for i in range(100)]"""
>>> timeit.timeit('[int(v) for v in l]', setup)
25.133059591551955
>>> timeit.timeit('list(map(int, l))', setup)
19.705547827217515
>>> timeit.timeit('[*map(int, l)]', setup)
19.45838406513076

Hinweis: In Python 3 scheinen 4 Elemente der Übergangspunkt zu sein (3 in Python 2), an dem das Verständnis etwas schneller ist, obwohl das Entpacken des Generators immer noch schneller ist als bei Listen mit mehr als 1 Element.

Jim
quelle