650 Stimmen

Eine Liste in Python 3.x mit map() zurückgeben

Ich versuche, eine Liste in Hexadezimalzahlen abzubilden und dann die Liste an anderer Stelle zu verwenden. In Python 2.6, war dies einfach:

A: Python 2.6:

>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']

In Python 3.1 wird jedoch ein map-Objekt zurückgegeben.

B: Python 3.1:

>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>

Wie kann ich die zugeordnete Liste abrufen (wie in A oben) auf Python 3.x?

Oder gibt es eine bessere Möglichkeit, dies zu tun? Mein anfängliches Listenobjekt hat etwa 45 Einträge und ich möchte sie in Hex umwandeln.

913voto

Kenan Banks Punkte 196831

Tun Sie dies:

list(map(chr,[66,53,0,94]))

In Python 3+ geben viele Prozesse, die über Iterablen iterieren, selbst Iteratoren zurück. In den meisten Fällen wird dadurch Speicher gespart, und die Dinge sollten schneller gehen.

Wenn Sie nur über diese Liste iterieren wollen, brauchen Sie sie nicht einmal in eine Liste umzuwandeln, denn Sie können immer noch über die Liste iterieren. map Objekt wie folgt:

# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
    print(ch)

181voto

Israel Unterman Punkte 12374

Neu und übersichtlich in Python 3.5:

[*map(chr, [66, 53, 0, 94])]

Dank an Zusätzliche Verallgemeinerungen zum Auspacken

UPDATE

Auf der Suche nach kürzeren Wegen habe ich entdeckt, dass auch dieser Weg funktioniert:

*map(chr, [66, 53, 0, 94]),

Das Entpacken funktioniert auch bei Tupeln. Beachten Sie das Komma am Ende. Dies macht es zu einem Tupel mit 1 Element. Das heißt, es ist äquivalent zu (*map(chr, [66, 53, 0, 94]),)

Er ist nur um ein Zeichen kürzer als die Version mit den Aufzählungsklammern, aber meiner Meinung nach besser zu schreiben, weil man gleich mit dem Sternchen - der Erweiterungssyntax - beginnt, so dass ich das Gefühl habe, dass es weniger anstrengend ist :)

124voto

Mark Rushakoff Punkte 236626

Warum tust du das nicht?

[chr(x) for x in [66,53,0,94]]

Das nennt man Listenverständnis. Sie können viele Informationen bei Google finden, aber hier ist der Link zur Python (2.6) Dokumentation über Listenauffassungen . Sie sind vielleicht mehr interessiert an die Python 3-Dokumentation Allerdings.

28voto

Boris Gorelik Punkte 27067

Die Kartenfunktion mit Listenrückgabe hat den Vorteil, dass sie vor allem bei interaktiven Sitzungen Tipparbeit spart. Sie können definieren lmap Funktion (in Anlehnung an die Python2-Funktion imap ), die Liste zurückgibt:

lmap = lambda func, *iterable: list(map(func, *iterable))

Dann rufen Sie lmap anstelle von map wird die Aufgabe erfüllen: lmap(str, x) ist um 5 Zeichen (in diesem Fall 30%) kürzer als list(map(str, x)) und ist sicherlich kürzer als [str(v) for v in x] . Sie können ähnliche Funktionen erstellen für filter auch.

Es gab einen Kommentar zur ursprünglichen Frage:

Ich würde eine Umbenennung in Getting map() vorschlagen, um eine Liste in Python 3.* zurückzugeben, da es für alle Python3-Versionen gilt. Gibt es eine Möglichkeit, dies zu tun? - meawoppl 24. Januar um 17:58

Es でございます möglich, aber es ist eine sehr schlechte Idee. Nur zum Spaß, hier ist, wie Sie können ( sollte aber nicht ) es tun:

__global_map = map #keep reference to the original map
lmap = lambda func, *iterable: list(__global_map(func, *iterable)) # using "map" here will cause infinite recursion
map = lmap
x = [1, 2, 3]
map(str, x) #test
map = __global_map #restore the original map and don't do that again
map(str, x) #iterator

7voto

ShadowRanger Punkte 120358

Konvertieren mein alter Kommentar für eine bessere Sichtbarkeit: Für einen "besseren Weg, dies zu tun" ohne map Wenn Ihre Eingaben bekanntermaßen ASCII-Ordinale sind, ist es im Allgemeinen viel schneller, in bytes und dekodieren, a la bytes(list_of_ordinals).decode('ascii') . Das bringt Ihnen eine str der Werte, aber wenn Sie eine list für Veränderlichkeit oder ähnliches, können Sie es einfach konvertieren (und es ist immer noch schneller). Zum Beispiel, in ipython Mikrobenchmarks, die 45 Eingänge umwandeln:

>>> %%timeit -r5 ordinals = list(range(45))
... list(map(chr, ordinals))
...
3.91 µs ± 60.2 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... [*map(chr, ordinals)]
...
3.84 µs ± 219 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... [*bytes(ordinals).decode('ascii')]
...
1.43 µs ± 49.7 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... bytes(ordinals).decode('ascii')
...
781 ns ± 15.9 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

Wenn Sie es als str benötigt es ~20% der Zeit des schnellsten map Lösungen; selbst bei der Umrechnung auf die Liste sind es immer noch weniger als 40 % der schnellsten map Lösung. Massenkonvertierung über bytes et bytes.decode dann Massenkonvertierung zurück zu list spart eine Menge Arbeit, sondern funktioniert, wie bereits erwähnt, nur, wenn alle Eingaben ASCII-Ordinalzeichen sind (oder Ordinalzeichen in einer ein Byte pro Zeichen umfassenden landesspezifischen Kodierung, z. B. latin-1 ).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X