在python中使用重复键创建字典

nrj*_*nrj 44 python dictionary

我有以下列表,其中包含具有不同值的重复汽车注册号.我想把它转换成一个字典,接受汽车注册号的多个键.到目前为止,当我尝试将列表转换为字典时,它消除了其中一个键.有人可以告诉我如何使用重复键创建字典列表是:

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
Run Code Online (Sandbox Code Playgroud)

我试过的代码是:

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()
Run Code Online (Sandbox Code Playgroud)

NPE*_*NPE 104

Python词典不支持重复键.一种方法是在字典中存储列表或集合.

实现此目的的一种简单方法是使用defaultdict:

from collections import defaultdict

data_dict = defaultdict(list)
Run Code Online (Sandbox Code Playgroud)

你所要做的就是更换

data_dict[regNumber] = details
Run Code Online (Sandbox Code Playgroud)

data_dict[regNumber].append(details)
Run Code Online (Sandbox Code Playgroud)

你会得到一份列表字典.

  • 起初,我没有理解这相当于将字典键的值自己声明为列表并附加到它上面.虽然消除了几行样板,但这很好.`如果不是data_dict中的my_key:``data_dict [my_key] = list()` (2认同)

Sco*_*pil 37

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

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

出来的例子:

>>> 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]}
Run Code Online (Sandbox Code Playgroud)

  • 为什么不只是`如果键不在自己:`而不是`try:`/`除了KeyError:`? (5认同)
  • @kirill https://docs.python.org/3.4/glossary.html#term-eafp (2认同)

小智 9

可以参考以下文章:http : //www.wellho.net/mouth/3934_Multiple-identical-keys-in-a-Python-dict-yes-you-can-.html

在字典中,如果一个键是一个对象,则不存在重复问题。

例如:

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}
Run Code Online (Sandbox Code Playgroud)

  • 如何使用键“k”获取所有值?唯一的方法是顺序比较,这失去了使用哈希字典的意义。 (4认同)
  • @minion 就在这里。要么存储对这些对象的引用以访问这些值,要么必须进行迭代。在前一种情况下,您不妨将数据放入键对象中并忘记字典,在后一种情况下,您可以只使用元组列表。这并没有真正做到上面所说的那样——你只是让钥匙变得不同而已。这可能会解决你的问题,但到那时,字典就变成了错误的数据结构,你只有一个不需要的间接层。 (2认同)

Don*_*sto 7

你不能有一个带有重复键的dict来定义!Insted您可以使用单个键,并使用具有该键的元素列表作为值.

所以你可以按照这些步骤:

  1. 查看当前元素(初始设置的)键是否进入最终字典.如果是,请转到步骤3
  2. 用密钥更新字典
  3. 附加到dict [key]列出新值
  4. 重复[1-3]


Blc*_*ght 7

我刚刚发布了一个问题的答案,该问题随后被关闭为该问题的副本(我认为有充分的理由),但我很惊讶地看到我提出的解决方案未包含在此处的任何答案中。

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!
Run Code Online (Sandbox Code Playgroud)

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


tot*_*ico 6

如果您只想在需要时使用列表,并在任何其他情况下使用值,那么您可以这样做:

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])
Run Code Online (Sandbox Code Playgroud)

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

dl = DictList()
dl['a']  = 1
dl['b']  = 2
dl['b'] = 3
Run Code Online (Sandbox Code Playgroud)

这将存储以下内容{'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
Run Code Online (Sandbox Code Playgroud)

这将生成与上面相同的输出:{'a': 1, 'b': [2, 3]}.


注意:此实现依赖于不存在的append方法(在您存储的值中)。如果您存储的值是列表,这可能会产生意外结果。例如,

dl = DictList()
dl['a']  = 1
dl['b']  = [2]
dl['b'] = 3
Run Code Online (Sandbox Code Playgroud)

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