用Python创建具有重复键的字典

问题描述 投票:-2回答:1

我有以下列表,其中包含具有不同值的重复的汽车登记号。我想将其转换为字典,该字典接受汽车登记号的多个键。

到目前为止,当我尝试将列表转换为字典时,它消除了键之一。如何制作具有重复键的字典?

列表是:

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
1个回答
109
投票

Python字典不支持重复键。一种解决方法是将列表或集合存储在字典中。

一种简单的方法是使用defaultdict

defaultdict

您要做的就是替换

from collections import defaultdict

data_dict = defaultdict(list)

with

data_dict[regNumber] = details

您将获得列表的字典。


40
投票

您可以在Python中更改内置类型的行为。对于您的情况,创建一个dict子类非常容易,该子类将自动将重复的值存储在同一键下的列表中:

data_dict[regNumber].append(details)

输出示例:

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

7
投票

您不能为字典定义重复的键!相反,您可以使用单个键,也可以使用具有该键的元素列表作为值。

因此您可以按照以下步骤操作:

  1. 查看当前元素的(初始集合的)键是否在最终字典中。如果是,请转到步骤3
  2. 用键更新字典
  3. 将新值添加到dict [key]列表中
  4. 重复[1-3]

3
投票

您在字典中不能有重复的键。使用列表的字典:

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

如果要仅在必要时列出列表,以及其他情况下的值,则可以执行以下操作:

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)

然后您可以执行以下操作:

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


CAVEAT:此实现依赖于{'a': 1, 'b': [2, 3]}方法的不存在(在您存储的值中)。这可能会产生如果要存储的值是列表,则结果出乎意料。例如,

append

将产生与dl = DictList() dl['a'] = 1 dl['b'] = [2] dl['b'] = 3 之前相同的结果,但可能会期望以下结果:{'a': 1, 'b': [2, 3]}


3
投票

您可以参考以下文章:{'a': 1, 'b': [[2], 3]}

在字典中,如果键是对象,则没有重复的问题。

例如:

http://www.wellho.net/mouth/3934_Multiple-identical-keys-in-a-Python-dict-yes-you-can-.html

1
投票

[我刚刚发布了一个问题的答案,该问题后来作为该问题的重复而被关闭(我认为有充分的理由,但是我很惊讶地看到我的提议解决方案未包含在此处的任何答案中。) >

而不是使用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

这很像使用defaultdict,但是您不需要特殊的数据类型。调用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! 时,它将检查字典中是否已存在第一个参数(键)。如果找不到任何内容,它将第二个参数(默认值,在这种情况下为空列表)分配为键的新值。如果该密钥确实存在,则不会执行任何特殊操作(默认设置为未使用)。无论哪种情况,都会返回值(无论是旧值还是新值),因此我们可以无条件地调用它的setdefault,因为它应该始终是一个列表。

© www.soinside.com 2019 - 2024. All rights reserved.