Diese möchte ich kombinieren:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
In ein einziges Wörterbuch:
{'name': 'Monty', 'age': 42, 'food': 'spam'}
Guido
Diese möchte ich kombinieren:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
In ein einziges Wörterbuch:
{'name': 'Monty', 'age': 42, 'food': 'spam'}
Dan Lenski
So was:
keys = ['a', 'b', 'c']
values = [1, 2, 3]
dictionary = dict(zip(keys, values))
print(dictionary) # {'a': 1, 'b': 2, 'c': 3}
Voila 🙂 Die paarweise dict
Konstrukteur u zip
Funktion sind unglaublich nützlich.
Es ist erwähnenswert, dass dictionary = {zip(keys, values)}
wird nicht funktionieren. Sie müssen explizit als deklarieren dict(...)
– Fernando Wittmann
28. August 2019 um 15:52 Uhr
Ich bin mir nicht sicher, warum du das erwarten würdest, @FernandoWittmann. {thing}
ist syntaktischer Zucker, um a zu konstruieren set()
ein Element enthält. {*iterable}
ist syntaktischer Zucker, um a zu konstruieren set
mehrere Elemente enthalten. {k:v}
oder {**mapping}
Wille konstruieren a dict
aber das ist syntaktisch ziemlich unterschiedlich.
– Dan Lenski
28. August 2019 um 16:41 Uhr
Danke für den Kommentar Dan. Sie haben Recht. Meine Verwirrung geschah, weil ich normalerweise die Sintax verwende {}
für Wörterbücher. In der Tat, wenn wir es versuchen type({})
die Ausgabe ist dict
. Aber in der Tat, wenn wir es versuchen type({thing})
dann ist die Ausgabe set
.
– Fernando Wittmann
28. August 2019 um 17:42 Uhr
Ich bin hergekommen, falls wir es besser machen können {k:v for k, v in zip(keys, values)}
. Es stellt sich heraus, dass wir es können. +1.
– JG
23. Januar 2020 um 14:28 Uhr
@FernandoWittmann du hast recht, dass es verwirrend ist. {[thing1, thing2, … thingN]}
erstellt eine Menge für einen beliebigen Wert von N != 0
; aber für N == 0
es schafft ein leeres dict
und Sie müssen tun set()
um eine leere Menge zu erstellen. Es ist ein etwas unglücklich, und PoLS-Verletzung, Warze von Python, aufgrund der Tatsache, dass Python hatte dict
-Literale lange vorher set
-Literale.
– Dan Lenski
29. Oktober 2020 um 0:14 Uhr
Russland muss Putin entfernen
Stellen Sie sich vor, Sie haben:
keys = ('name', 'age', 'food') values = ('Monty', 42, 'spam')
Was ist der einfachste Weg, um das folgende Wörterbuch zu erstellen?
dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
dict
Konstrukteur mit zip
new_dict = dict(zip(keys, values))
In Python 3 gibt zip jetzt einen faulen Iterator zurück, und dies ist jetzt der leistungsfähigste Ansatz.
dict(zip(keys, values))
erfordert die einmalige globale Suche jeweils für dict
und zip
aber es bildet keine unnötigen Zwischendatenstrukturen oder muss sich mit lokalen Suchen in der Funktionsanwendung befassen.
Ein enger Nachfolger zur Verwendung des dict-Konstruktors ist die Verwendung der nativen Syntax eines dict-Verständnisses (kein aufführen Verständnis, wie andere es fälschlicherweise ausgedrückt haben):
new_dict = {k: v for k, v in zip(keys, values)}
Wählen Sie dies, wenn Sie basierend auf den Schlüsseln oder Werten zuordnen oder filtern müssen.
In Python2, zip
gibt eine Liste zurück, um das Erstellen einer unnötigen Liste zu vermeiden, verwenden Sie izip
stattdessen (aliased to zip kann Codeänderungen reduzieren, wenn Sie zu Python 3 wechseln).
from itertools import izip as zip
Das ist also immer noch (2.7):
new_dict = {k: v for k, v in zip(keys, values)}
izip
aus itertools
wird zip
in Python3. izip
ist besser als zip für Python 2 (weil es die unnötige Listenerstellung vermeidet) und ideal für 2.6 oder niedriger:
from itertools import izip
new_dict = dict(izip(keys, values))
Auf alle Fälle:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
Schauen wir uns die Hilfe an dict
Wir sehen, dass es eine Vielzahl von Argumentationsformen braucht:
>>> help(dict)
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| dict(**kwargs) -> new dictionary initialized with the name=value pairs
| in the keyword argument list. For example: dict(one=1, two=2)
Der optimale Ansatz besteht darin, iterable zu verwenden und gleichzeitig das Erstellen unnötiger Datenstrukturen zu vermeiden. In Python 2 erstellt zip eine unnötige Liste:
>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
In Python 3 wäre das Äquivalent:
>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
und Python 3 zip
erstellt lediglich ein iterierbares Objekt:
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
Da wir das Erstellen unnötiger Datenstrukturen vermeiden möchten, möchten wir normalerweise die von Python 2 vermeiden zip
(da es eine unnötige Liste erstellt).
Dies ist ein Generatorausdruck, der an den dict-Konstruktor übergeben wird:
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
oder gleichwertig:
dict((k, v) for k, v in zip(keys, values))
Und dies ist ein Listenverständnis, das an den dict-Konstruktor übergeben wird:
dict([(k, v) for k, v in zip(keys, values)])
In den ersten beiden Fällen wird eine zusätzliche Schicht nicht operativer (also unnötiger) Berechnungen über die Zip-Iterable gelegt, und im Fall des Listenverständnisses wird unnötigerweise eine zusätzliche Liste erstellt. Ich würde erwarten, dass sie alle weniger leistungsfähig sind, und sicherlich nicht mehr.
In 64-Bit-Python 3.8.2, bereitgestellt von Nix, auf Ubuntu 16.04, geordnet vom schnellsten zum langsamsten:
>>> min(timeit.repeat(lambda: dict(zip(keys, values))))
0.6695233230129816
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
0.6941362579818815
>>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
0.8782548159942962
>>>
>>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
1.077607496001292
>>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
1.1840861019445583
dict(zip(keys, values))
gewinnt sogar mit kleinen Sätzen von Schlüsseln und Werten, aber bei größeren Sätzen werden die Leistungsunterschiede größer.
Ein Kommentator sagte:
min
scheint ein schlechter Weg zu sein, um die Leistung zu vergleichen. Sicherlichmean
und/odermax
wären viel nützlichere Indikatoren für die tatsächliche Nutzung.
Wir gebrauchen min
weil diese Algorithmen deterministisch sind. Wir wollen die Leistung der Algorithmen unter den bestmöglichen Bedingungen kennen.
Wenn das Betriebssystem aus irgendeinem Grund hängt, hat das nichts mit dem zu tun, was wir zu vergleichen versuchen, also müssen wir diese Art von Ergebnissen aus unserer Analyse ausschließen.
Wenn wir benutzten mean
würden solche Ereignisse unsere Ergebnisse stark verfälschen, und wenn wir sie verwenden würden max
wir erhalten nur das extremste Ergebnis – dasjenige, das am wahrscheinlichsten von einem solchen Ereignis betroffen ist.
Ein Kommentator sagt auch:
In Python 3.6.8 ist das Diktatverständnis bei Verwendung von Mittelwerten tatsächlich noch schneller, um etwa 30% für diese kleinen Listen. Für größere Listen (10.000 Zufallszahlen) ist die
dict
Anruf ist etwa 10 % schneller.
Ich nehme an, wir meinen dict(zip(...
mit 10k Zufallszahlen. Das klingt nach einem ziemlich ungewöhnlichen Anwendungsfall. Es macht Sinn, dass die direktesten Aufrufe in großen Datensätzen dominieren würden, und ich wäre nicht überrascht, wenn OS-Hänger dominieren würden, wenn man bedenkt, wie lange es dauern würde, diesen Test auszuführen, was Ihre Zahlen weiter verzerren würde. Und wenn Sie verwenden mean
oder max
Ich würde Ihre Ergebnisse für bedeutungslos halten.
Lassen Sie uns eine realistischere Größe für unsere Top-Beispiele verwenden:
import numpy
import timeit
l1 = list(numpy.random.random(100))
l2 = list(numpy.random.random(100))
Und das sehen wir hier dict(zip(...
läuft in der Tat bei größeren Datensätzen um etwa 20% schneller.
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(l1, l2)}))
9.698965263989521
>>> min(timeit.repeat(lambda: dict(zip(l1, l2))))
7.9965161079890095
Ab Mitte 2019 (Python 3.7.3) finde ich unterschiedliche Timings. %%timeit gibt 1,57 \pm 0,019 Mikrosekunden für zurück dict(zip(headList, textList))
& 1,95 \pm 0,030 Mikrosekunden für {k: v for k, v in zip(headList, textList)}
. Ich würde Ersteres wegen der Lesbarkeit und Geschwindigkeit vorschlagen. Offensichtlich kommt dies beim min() vs mean() Argument für timeit an.
– Mark_Anderson
2. Juli 2019 um 15:06 Uhr
Es scheint, dass Sie sagen, dass das Diktatverständnis am schnellsten ist, aber dann in der Leistungsüberprüfung, dict(zip(keys, values))
sieht schneller aus. Vielleicht hast du vergessen etwas zu aktualisieren?
– Loisaida Sam Sandberg
8. April 2020 um 2:57 Uhr
Kleine Anmerkung (bei Python 2 EOL weitgehend irrelevant): Sie können verwenden from future_builtins import zip
als Alternative zu from itertools import izip as zip
Das ist etwas expliziter, wenn es darum geht, den Import in Bezug auf das Erhalten von Python 3 zu beschreiben zip
als Ersatz für normale zip
. Es ist genau gleichbedeutend mit klar (future_builtins.zip
ist selbst nur ein Alias von itertools.izip
).
– ShadowRanger
29. Oktober 2020 um 18:24 Uhr
Mike Davis
Versuche dies:
>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}
In Python 2 ist es im Vergleich zu auch sparsamer im Speicherverbrauch zip
.
Richtig für Python2, aber in Python 3, zip
ist bereits sparsam im Speicherverbrauch. docs.python.org/3/library/functions.html#zip Tatsächlich kann man das sehen six
Verwendet zip
in Python 3 zu ersetzen itertools.izip
in Python2 pythonhosted.org/six .
– Pedro Cattori
17. Februar 2017 um 14:56 Uhr
iny
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
out = dict(zip(keys, values))
Ausgabe:
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Sie können Wörterbuchverständnisse auch in Python ≥ 2.7 verwenden:
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> {k: v for k, v in zip(keys, values)}
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Ein natürlicherer Weg ist die Verwendung des Wörterbuchverständnisses
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dict = {keys[i]: values[i] for i in range(len(keys))}
jfs
Wenn Sie Schlüssel oder Werte transformieren müssen, bevor Sie ein Wörterbuch erstellen, a Generatorausdruck könnte verwendet werden. Beispiel:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))
Schau mal Programmieren wie ein Pythonista: Idiomatisches Python.