2010-05-14 6 views
8

Ich habe eine Liste von Werten und möchte sie in ein Dictionary einfügen, das jeden Wert seinem Index zuordnet.Pythonische Art, Listenelemente mit ihren Indizes zu verknüpfen

Ich kann es auf diese Weise tun:

>>> t = (5,6,7) 
>>> d = dict(zip(t, range(len(t)))) 
>>> d 
{5: 0, 6: 1, 7: 2} 

dies ist nicht schlecht, aber ich bin für etwas elegantere suchen.

ich über die folgenden gekommen sind, aber es macht das Gegenteil von dem, was ich brauche:

>>> d = dict(enumerate(t)) 
>>> d 
{0: 5, 1: 6, 2: 7} 

Sie bitte Ihre Lösungen teilen,
Danke

EDIT: Python 2.6.4

Für Listen, die 1000 Elemente enthalten, ist die dict (zip) Version die schnellste, der Generator und die Liste Verständnis Versionen sind praktisch identisch und sie sind ~ 1,5 mal langsamer und die Funktionskarte (umgekehrt) ist wesentlich langsamer.

$ python -mtimeit es "t = range (int (1e3))" "d = dict (zip (t, Bereich (len (t))))"
1000 Schleifen, am besten von 3: 277 usec pro Schleife

$ Python -mtimeit es "t = range (int (1E3))", "d = dict ([(y, x) für x, y in aufzählen (t)])"
1000 loops, best of 3: 426 usec pro Schleife

$ python -mtime it -s "t = range (int (1e3))" "d = dict ((y, x) für x, y in enumerate (t)) "
1000 Schleifen, best of 3: 437 Usec pro Schleife

$ python -mtimeit -s "t = Bereich (int (1e3))" "d = dict (Karte (umgekehrt, enumerieren (t)))"
100 Schleifen, best of 3: 3,66 ms pro Schleife

Ich habe versucht, die gleichen Tests für längere und für kürzere Listen (1e2, 1e4, 1e5) und die Zeit pro Schleife läuft linear mit der Länge der Liste.

Könnte jemand Zeit py 2.7+ Version?

+0

Ich bin neugierig - welche der Implementierungen ist schneller? Übrigens, Chewy, welche Version von Python benutzt du? –

Antwort

13

Sie können ein Listenverständnis (oder einen Generator, abhängig von Ihrer Python-Version) verwenden, um einen einfachen In-Place-Austausch für Ihr zweites Beispiel durchzuführen.


Mit einer Liste Verständnis:

d = dict([(y,x) for x,y in enumerate(t)]) 

einen Generator Ausdruck verwenden (Python 2.4 und höher):

d = dict((y,x) for x,y in enumerate(t)) 
+2

Sie brauchen das '[]' nicht dort. 'dict' funktioniert gut mit einem Generator-Ausdruck (spart das Erstellen einer Zwischenliste) –

+1

Ja, deshalb habe ich" abhängig von Ihrer Python-Version "geschrieben. Generatoren gibt es schon seit langer Zeit (seit 2.4), also werde ich beide – kibibu

+1

Wo wird Python <2.4 verwendet? – jfs

4
>>> dict((x,i) for i,x in enumerate(t)) 
{5: 0, 6: 1, 7: 2} 
>>> 
2

Sind alle Elemente einzigartig (dh deine Liste wäre niemals 5,6,7,7)? Die Dict-Lösung funktioniert nur, wenn alle Elemente eindeutig sind.

Durch das Speichern des Indexes duplizieren Sie im Wesentlichen Informationen, da Sie einfach den aktuellen Index des Elements in der Liste abfragen können. Das Duplizieren von Informationen ist normalerweise nicht die beste Idee, da es die Möglichkeit bietet, dass ein Datensatz mit dem anderen nicht mehr synchron ist.

Wenn die Liste geändert wird, verhindert auch nichts, dass Sie versehentlich denselben Index mehreren Objekten zuweisen.

Warum versuchen Sie, den Indexwert zu speichern, wenn Sie einfach den Index von der Liste abrufen konnten?

+0

Alle Listenelemente sind einzigartig. Ich speichere den Index für schnelles Nachschlagen in einer anderen Datenstruktur. –

+0

Das klingt wie eine nutzlose Ebene der Umleitung, wenn alle Elemente eindeutig sind, testet auf Mitgliedschaft mit 'in' und Index mit' index() '. Ich nehme an, dass Sie sich vorstellen, dass ein Hash-Map-basiertes Wörterbuch Ihnen schnelleres Nachschlagen ermöglicht als 'index()'. In Python ist eine vorzeitige Optimierung wirklich böse, weil Ihre Intuitionen über "schneller" oft falsch sind, bis sie tatsächlich zeitlich abgestimmt sind. Lass es funktionieren, dann finde heraus, wo du langsam bist, zusätzliche Komplexität ist es nicht wert. – msw

+0

@Dragan, ändern Sie Ihre Liste oder bleiben sie statisch? –

0

Ich mag das Diktat (zip (t, Bereich (len (t)))) am besten.

+0

Warum? Ist es schneller? –

+0

Es ist kurz, einfach und auf den Punkt. – Arafangion

12

In python2.7 + können Sie es wie folgt

schreiben
>>> t = (5,6,7) 
>>> d = {x:i for i,x in enumerate(t)} 
>>> print d 
{5: 0, 6: 1, 7: 2} 
+0

+1 für die Darstellung der Schönheit von Py3ks dict comprehensions. – Dustin

2

Wie jeder schon geschrieben hat, in Python 2.6 ich folgendes als die pythonic betrachten würde:

>>> dict((x, i) for i, x in enumerate(t)) 
{5: 0, 6: 1, 7: 2} 

Noch in einem Moment der funktionalen Raserei würde ich schreiben:

>>> dict(map(reversed, enumerate(t))) 
{5: 0, 6: 1, 7: 2}