2012-05-19 4 views
28

У меня есть следующий список, который содержит повторяющиеся регистрационные номера автомобилей с разными значениями. Я хочу преобразовать его в словарь, который принимает эти несколько ключей регистрационных номеров автомобилей. Пока я пытаюсь преобразовать список в словарь, он устраняет один из ключей. Может кто-то показать мне, как сделать словарь с повторяющимися ключами Список является:сделать словарь с дублирующими ключами в 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 

код, который я попробовал это:

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

Если словарь допускает дубликаты ключей с разными значениями, которые вы ожидаете получить при просмотре значения для такого ключа позже? – martineau

ответ

5

Вы не можете иметь Dict с повторяющимися ключами для определения! Устанавливается, что вы можете использовать один ключ и, как значение, список элементов, имеющих этот ключ.

Таким образом, вы можете следить за те шаги:

  1. Смотрите, если ключ текущего элемента (вашего исходного набора) является в окончательном Dict. Если же, перейдите к шагу 3
  2. Update Dict с ключом
  3. Append для Сыроватскога [ключ] список нового значения
  4. Repeat [1-3]
77

Python словари не поддерживают дубликаты ключей , Один из способов - хранить списки или наборы внутри словаря.

Один простой способ добиться этого с помощью defaultdict:

from collections import defaultdict 

data_dict = defaultdict(list) 

Все, что вам нужно сделать, это заменить

data_dict[regNumber] = details 

с

data_dict[regNumber].append(details) 

и вы получите словарь списков.

+3

+1 Хороший способ сделать это, я не буду писать строки кода об этом после прочтения этого: – DonCallisto

+1

+1 У меня была очень жуткая структура данных, написанная мною. Несмотря на то, что ваш подход сохраняет мою структуру данных жуткой! Но намного меньше: D – user1252280

+1

Это действительно приятно. Спасибо за идею. –

1

Вы не можете дублировать ключи в словаре. Как насчет диктата списков?

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

Но решение 'defaultdict' лучше, чем делать это вручную (ответ aix) – Oskarbi

+0

ya этот работает отлично. спасибо – nrj

+1

вместо 'hash_key', мы можем просто использовать' if not regNumber в data_dict' –

29

Вы можете изменить поведение встроенных типов в python. В вашем случае это действительно легко создать Dict подкласс, который будет хранить дублированные значения в списках под тем же ключом автоматически:

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

вне положенное пример:

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

Почему не просто 'if key not in self:' вместо 'try:'/'except KeyError:'? –

+0

Разве это не то же самое, как: 'из коллекции импорта defaultdict d = defaultdict (список) d [' тест '] присоединять (1) d. [' Тест '] добавить (2) d [.' Тест '] .append (3)' Или я могу что-то упустить? –

0

Если вы хотите есть списки только когда они необходимы, а значения в любых других случаях, то вы можете 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]) 

вы можете сделать следующее:

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

Будет сохранено следующее: {'a': 1, 'b': [2, 3]}.


Я предпочитаю использовать эту реализацию, когда я хочу, чтобы иметь обратные/обратные словари, в этом случае я просто сделать:

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

Какой будет генерировать тот же результат, что и выше: {'a': 1, 'b': [2, 3]}.


CAVEAT: Эта реализация опирается на не-существовании append метода (в значениях вы сохраняете). Это может привести к непредвиденным результатам , если значения, которые вы храните, являются списками. Например,

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

будет производить тот же результат, как и раньше {'a': 1, 'b': [2, 3]}, но можно было бы ожидать следующее: {'a': 1, 'b': [[2], 3]}.

Смежные вопросы