2012-05-19 50 views
28

Tengo la siguiente lista que contiene números de registro de automóviles duplicados con diferentes valores. Quiero convertirlo en un diccionario que acepte estas claves múltiples de números de registro de automóviles. Hasta ahora, cuando trato de convertir la lista al diccionario, elimina una de las claves. Alguien me puede mostrar cómo hacer diccionario con claves duplicadas La lista es:crear diccionario con claves duplicadas en 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 

El código que he tratado es:

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

Si un diccionario permitía la duplicación de claves con diferentes valores asociados, ¿cuál esperaría que se recuperara cuando busque el valor de dicha clave más adelante? – martineau

Respuesta

5

No se puede tener un diccionario con duplicados de las llaves para la definición! Insist en que puede usar una sola clave y, como valor, una lista del elemento que tenía esa clave.

para que pueda seguir los pasos:

  1. Ver si la clave del elemento actual (de la serie inicial) es en dict final. Si lo hace, vaya al paso 3
  2. actualización dict con llave
  3. Anexar al dict [clave] listar el nuevo valor
  4. Repetir [1-3]
77

Python diccionarios no son compatibles con duplicados de las llaves . Una forma de evitarlo es almacenar listas o conjuntos dentro del diccionario.

Una manera fácil de lograr esto es mediante el uso de defaultdict:

from collections import defaultdict 

data_dict = defaultdict(list) 

Todo lo que tiene que hacer es reemplazar

data_dict[regNumber] = details 

con

data_dict[regNumber].append(details) 

y obtendrá una diccionario de listas.

+3

+1 Una buena manera de hacerlo, no voy a escribir ninguna línea más de código sobre eso después de leer esto :) – DonCallisto

+1

+1 Tenía una estructura de datos muy espeluznante escrita por mí mismo. ¡Aunque incluir tu enfoque mantiene mi estructura de datos escalofriante! Pero mucho menos: D – user1252280

+1

Esto es realmente bueno. Gracias por la idea –

1

No puede tener claves duplicadas en un diccionario. ¿Qué tal un dict de listas?

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

Pero la solución 'defaultdict' es mejor que hacer esto manualmente (la respuesta de aix) – Oskarbi

+0

ya esta funciona bien. gracias – nrj

+1

en lugar de 'hash_key', podemos usar' if not regNumber en data_dict' –

29

Puede cambiar el comportamiento de los tipos incorporados en python. Para su caso es muy fácil crear subclase dict que almacenará los valores duplicados en las listas bajo la misma clave de forma automática:

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

fuera ponga ejemplo:

>>> 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

¿Por qué no simplemente 'si la clave no está en sí mismo:' en lugar de 'try:'/'excepto KeyError:'? –

+0

este no es el mismo que: 'de colecciones importar defaultdict d = defaultdict (lista) d [' prueba '] append (1) d. [' Prueba '] append (2) d [.' Test '] .append (3)' ¿O puedo perder algo? –

0

Si quieres tienen listas sólo cuando son necesarios, y los valores en cualquier otro caso, entonces se puede 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]) 

entonces usted puede hacer lo siguiente:

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

Que almacenará el siguiente {'a': 1, 'b': [2, 3]}.


que tienden a utilizar esta aplicación cuando quieren tener diccionarios inversos/inversas, en cuyo caso simplemente hacer:

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

que generará el mismo resultado que el anterior: {'a': 1, 'b': [2, 3]}.


advertencia: Esta aplicación se basa en la inexistencia de la append método (en los valores que se está almacenando). Esto podría producir resultados inesperados si los valores que está almacenando son listas. Por ejemplo,

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

produciría el mismo resultado que antes {'a': 1, 'b': [2, 3]}, pero uno podría esperar el siguiente: {'a': 1, 'b': [[2], 3]}.

Cuestiones relacionadas