我有以下列表,其中包含具有不同值的重复汽车注册号。我想把它转换成一个字典,接受汽车注册号码的多个键。
到目前为止,当我尝试将列表转换为字典时,它消除了其中一个键。如何制作包含重复键的字典?
清单是:
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()
Python词典不支持重复键。一种方法是在字典中存储列表或集合。
一个简单的方法是使用defaultdict
:
from collections import defaultdict
data_dict = defaultdict(list)
你所要做的就是更换
data_dict[regNumber] = details
同
data_dict[regNumber].append(details)
你会得到一份列表字典。
您可以在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]}
你不能有一个带有重复键的dict来定义!相反,您可以使用单个键,并使用具有该键的元素列表作为值。
所以你可以按照以下步骤操作:
如果您希望仅在必要时使用列表,并在任何其他情况下使用值,则可以执行以下操作:
class DictList(dict):
def __setitem__(self, key, value):
try:
# Assumes there is a list on the key
self[key].append(value)
except KeyError: # If it fails, because there is no key
super(DictList, self).__setitem__(key, value)
except AttributeError: # If it 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]}
。
您不能在字典中使用重复的密钥。使用列表的词典:
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)
您可以参考以下文章:http://www.wellho.net/mouth/3934_Multiple-identical-keys-in-a-Python-dict-yes-you-can-.html
在dict中,如果键是一个对象,则没有重复的问题。
例如:
class p(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
def __str__(self):
return self.name
d = {p('k'): 1, p('k'): 2}
我刚刚发布了一个问题的答案,这个问题被暂时关闭作为这个问题的副本(我认为有充分的理由),但我很惊讶地看到我提出的解决方案没有包含在这里的任何答案中。
您可以使用defaultdict
方法轻松地将值附加到字典中的列表上,而不是使用setdefault
或使用成员资格测试或手动异常处理。
results = {} # use a normal dictionary for our output
for k, v in some_data: # the keys may be duplicates
results.setdefault(k, []).append(v) # magic happens here!
这与使用defaultdict非常相似,但您不需要特殊的数据类型。当你调用setdefault
时,它会检查第一个参数(键)是否已经在字典中。如果没有找到任何内容,它会将第二个参数(默认值,在这种情况下为空列表)指定为键的新值。如果密钥确实存在,则不执行任何特殊操作(默认设置未使用)。在任何一种情况下,都会返回值(无论是旧的还是新的),因此我们可以无条件地在其上调用append
,因为它知道它应该始终是一个列表。