2012-05-19 9 views
28

Ich habe die folgende Liste, die doppelte Auto-Registrierungsnummern mit unterschiedlichen Werten enthält. Ich möchte es in ein Wörterbuch umwandeln, das diese Mehrfachschlüssel von Autokennzeichen annimmt. Wenn ich bisher versuche, eine Liste in ein Wörterbuch zu konvertieren, wird einer der Schlüssel gelöscht. Kann mir jemand zeigen, wie Wörterbuch mit Nachschlüssel machen Die Liste ist:machen Wörterbuch mit doppelten Schlüsseln in Python

EDF768, Bill Meyer, 2456, Vet_Parking 
TY5678, Jane Miller, 8987, AgHort_Parking 
GEF123, Jill Black, 3456, Creche_Parking 
ABC234, Fred Greenside, 2345, AgHort_Parking 
GH7682, Clara Hill, 7689, AgHort_Parking 
JU9807, Jacky Blair, 7867, Vet_Parking 
KLOI98, Martha Miller, 4563, Vet_Parking 
ADF645, Cloe Freckle, 6789, Vet_Parking 
DF7800, Jacko Frizzle, 4532, Creche_Parking 
WER546, Olga Grey, 9898, Creche_Parking 
HUY768, Wilbur Matty, 8912, Creche_Parking 
EDF768, Jenny Meyer, 9987, Vet_Parking 
TY5678, Jo King, 8987, AgHort_Parking 
JU9807, Mike Green, 3212, Vet_Parking 

Der Code, den ich versucht habe, ist:

data_dict = {} 
data_list = [] 

def createDictionaryModified(filename): 
    path = "C:\Users\user\Desktop" 
    basename = "ParkingData_Part3.txt" 
    filename = path + "//" + basename 
    file = open(filename) 
    contents = file.read() 
    print contents,"\n" 
    data_list = [lines.split(",") for lines in contents.split("\n")] 
    for line in data_list: 
    regNumber = line[0] 
    name = line[1] 
    phoneExtn = line[2] 
    carpark = line[3].strip() 
    details = (name,phoneExtn,carpark) 
    data_dict[regNumber] = details 
    print data_dict,"\n" 
    print data_dict.items(),"\n" 
    print data_dict.values() 
+6

Wenn ein Wörterbuch doppelte Schlüssel mit unterschiedlichen zugehörigen Werten zulässt, welche würden Sie erwarten, wenn Sie später den Wert für einen solchen Schlüssel nachschlagen? – martineau

Antwort

5

Sie können keine dict mit Nachschlüssel zur Definition haben! Sie können einen einzelnen Schlüssel und als Wert eine Liste von Elementen verwenden, die diesen Schlüssel hatten.

So können Sie diese Schritte durchführen:

  1. sehen, ob die (von Ihrem ersten Satz) des aktuellen Elements Schlüssel in die endgültige dict ist. Wenn ja, gehen Sie 3
  2. dict Update zu Schritt mit den wichtigsten
  3. anhängen dict [key] Liste den neuen Wert
  4. Repeat [1-3]
77

Python Wörterbücher unterstützen keine doppelten Schlüssel . Eine Möglichkeit besteht darin, Listen oder Mengen im Wörterbuch zu speichern.

Eine einfache Möglichkeit, dies zu erreichen, ist durch defaultdict mit:

from collections import defaultdict 

data_dict = defaultdict(list) 

Alles, was Sie tun müssen, ist

ersetzen
data_dict[regNumber] = details 

mit

data_dict[regNumber].append(details) 

und Sie werden eine bekommen Wörterbuch von Listen.

+3

+1 Schöne Art, das zu tun, werde ich nicht mehr Codezeile darüber nach dem Lesen dieses :) – DonCallisto

+1

+1 Hatte eine sehr unheimliche Datenstruktur von mir geschrieben. Obwohl das Einbeziehen Ihres Ansatzes meine Datenstruktur unheimlich macht! Aber viel weniger: D – user1252280

+1

Das ist wirklich nett. Danke für die Idee. –

1

Sie können in einem Wörterbuch keine doppelten Schlüssel haben. Was ist mit einem Diktat von Listen?

for line in data_list: 
    regNumber = line[0] 
    name = line[1] 
    phoneExtn = line[2] 
    carpark = line[3].strip() 
    details = (name,phoneExtn,carpark) 
    if not data_dict.has_key(regNumber): 
    data_dict[regNumber] = [details] 
    else: 
    data_dict[regNumber].append(details) 
+0

Aber die 'defaultdict' Lösung ist besser als das manuell (aix's Antwort) – Oskarbi

+0

ya das funktioniert gut. Danke – nrj

+1

anstelle von 'hash_key', können wir einfach 'wenn nicht regNumber in data_dict' verwenden –

29

Sie können das Verhalten der integrierten Typen in Python ändern. Für Ihren Fall ist es wirklich einfach dict Unterklasse zu erstellen, die duplizierte Werte in Listen unter dem gleichen Schlüssel automatisch gespeichert werden:

class Dictlist(dict): 
    def __setitem__(self, key, value): 
     try: 
      self[key] 
     except KeyError: 
      super(Dictlist, self).__setitem__(key, []) 
     self[key].append(value) 

heraus gesetzt Beispiel:

>>> d = dictlist.Dictlist() 
>>> d['test'] = 1 
>>> d['test'] = 2 
>>> d['test'] = 3 
>>> d 
{'test': [1, 2, 3]} 
>>> d['other'] = 100 
>>> d 
{'test': [1, 2, 3], 'other': [100]} 
+3

Warum nicht einfach 'if key nicht in self:' anstelle von 'try:'/'except KeyError:'? –

+0

Ist das nicht das gleiche wie: 'aus Sammlungen importieren defaultdict d = defaultdict (Liste) d [' test '] anhängen (1) d. [' Test '] anhängen (2) d [.' Test '] .append (3)' Oder darf ich etwas verpassen? –

0

Wenn Sie Listen wollen nur haben, wenn sie sind notwendig und Werte in allen anderen Fällen, dann können Sie DoThis:

class DictList(dict): 
    def __setitem__(self, key, value): 
     try: 
      # Assumes there is a list on the key 
      self[key].append(value) 
     except KeyError: # if fails because there is no key 
      super(DictList, self).__setitem__(key, value) 
     except AttributeError: # if fails because it is not a list 
      super(DictList, self).__setitem__(key, [self[key], value]) 

Sie können die folgenden dann tun:

Welches wird die folgenden {'a': 1, 'b': [2, 3]} speichern.


Ich neige dazu, diese Implementierung zu verwenden, wenn ich Reverse/inverse Wörterbücher haben will, wobei in diesem Fall habe ich einfach tun:

my_dict = {1: 'a', 2: 'b', 3: 'b'} 
rev = DictList() 
for k, v in my_dict.items(): 
    rev_med[v] = k 

, die wie oben die gleiche Leistung erzeugen: {'a': 1, 'b': [2, 3]}.


CAVEAT: Diese Implementierung beruht auf der Nicht-Existenz der append Methode (in den Werten Sie speichern). Dies kann zu unerwarteten Ergebnissen führen, wenn die Werte, die Sie speichern, Listen sind. Zum Beispiel

dl = DictList() 
dl['a'] = 1 
dl['b'] = [2] 
dl['b'] = 3 

würde das gleiche Ergebnis wie vor {'a': 1, 'b': [2, 3]} produzieren, aber man könnte folgendes erwartet: {'a': 1, 'b': [[2], 3]}.

Verwandte Themen