2012-05-19 29 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

你不能與定義重複鍵的字典! Insted你可以使用一個單一的鍵,並作爲值,具有該鍵的元素列表。

所以,你可以按照這些步驟:

  1. 看看當前元素的(你的初始設置)鍵是進入決賽字典。如果確實,則轉到步驟與關鍵
  2. 追加3
  3. 更新字典與dict [關鍵]列出新的價值
  4. 重複[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

這個工作正常。感謝 – nrj

+1

而不是'hash_key',我們可以使用'if not regNumber in 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

爲什麼不只是'如果鍵不在自己:'而不是'try:'/'除了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]}