一个键对应多个唯一值的Python字典
我有两个列表,对应于我想要的键:值对,例如:一个键对应多个唯一值的Python字典,python,list,dictionary,Python,List,Dictionary,我有两个列表,对应于我想要的键:值对,例如: list_1 = [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2] #(key) list_2 = [x,x,x,y,g,r,t,w,r,r,r,t,f,c,d] #(value) 我已经(某种程度上)能够通过以下方式创建字典:dict=dict(zip(列表1[列表2]) 但是,问题是,它只将“1”作为键拾取,并且还会导致该键的值列表中出现重复条目 有谁能建议一种创建字典的方法,以便只将list_2中的唯一值映射到相应的键 谢谢
list_1 = [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2] #(key)
list_2 = [x,x,x,y,g,r,t,w,r,r,r,t,f,c,d] #(value)
我已经(某种程度上)能够通过以下方式创建字典:dict=dict(zip(列表1[列表2])
但是,问题是,它只将“1”作为键拾取,并且还会导致该键的值列表中出现重复条目
有谁能建议一种创建字典的方法,以便只将list_2
中的唯一值映射到相应的键
谢谢
编辑:
我要查找的输出将是一个由1和2键入的字典,其中列表作为值,仅包含每个字典的唯一值,即:
dict = {1: [x,y,g,r,t,w], 2: [r,t,f,c,d]}
问题是你的钥匙太独特了。只有两个唯一的键1和2。因此,如果您正在创建字典,您不能同时拥有{1:x,1:y},例如,除非您将密钥更改为新的和唯一的 我会在你的目的中使用一个元组:
list(set(tuple(zip(list_1,list_2)))
该集合为您提供了唯一的映射,这就是删除重复项的原因 由于字典是一个集合,它不能包含两次相同的键,但它可以有一次键,然后是一个值列表,您可以使用单行方法
my_dict={key:[list_2[i]表示范围内的i(len(list_2)),如果list_1[i]==key]表示集合中的键(list_1)}
还是更经典的方法
my_dict={}
对于范围(len(列表_1))中的键_id:
如果列表1[键id]不在我的目录中:
my_dict[list_1[key_id]=[]
my_dict[list_1[key_id]].追加(list_2[key_id])
在这两种情况下,结果都是错误的
my_dict={1:['x',x',y',g',r',t',w',r',2:['r',r',t',f',c',d']
这类问题可以通过collections.defaultdict(set)
正确解决;defaultdict
可根据需要为每个键自动设置set
s,并且set
可统一与每个键相关的值:
from collections import defaultdict
mydict = defaultdict(set)
for k, v in zip(list_1, list_2):
mydict[k].add(v)
然后,您可以将结果转换为普通的dict
,其中包含列表
值,其中包含:
mydict = {k: list(v) for k, v in mydict.items()}
若必须保留值的顺序,则在现代Python上可以使用dict
s而不是set
(在较旧的Python上,可以使用collections.orderedict
):
转换为普通dict
,而list
值保持不变
如果输入已经排序,itertools.groupby
在理论上稍有效率(与使用dict
s的平均情况相比,实际的O(n)
),但实际上defaultdict
通常更快或更快(实施groupby
有一些不可避免的低效率)。仅为说明,groupby
解决方案是:
from itertools import groupby
from operator import itemgetter
mydict = {k: {v for _, v in grp} for k, grp in groupby(zip(list_1, list_2), key=itemgetter(0))]
# Or preserving order of insertion:
getval = itemgetter(1) # Construct once to avoid repeated construction
mydict = {k: list(dict.fromkeys(map(getval, grp)))
for k, grp in groupby(zip(list_1, list_2), key=itemgetter(0))]
{1:['x','y','g','r','t','w',2:['r','t','f','c','d']}
注意:
zip(keys,values) this will create a iterable of tuples, each tuple consist of one element from the keys and values.
(1,'x')
(1,'x')
如果list_1
中的元素是有序的(或者至少重复的值都在一起),您可以使用。您可以定义理想的输出是什么样的,以使其更接近a吗?因为示例代码没有执行您声称的操作(它将使dict
相当于键入mydict={1:list_2}
),不清楚你的目标是什么。没问题,只是更新了问题!谢谢,谢谢你的回答。对不起,我的问题可能没有应该的那么清楚,但我要寻找的输出是一个由1和2键入的字典,其中列表作为值,每个值只包含唯一的值,即:dict={1:[x,y,g,r,t,w],2:[r,t,f,c,d]}对于范围内的i(len(somesequence)):
只使用i
索引序列是一种反模式。您只需要对于键,zip中的值(list_1,list_2):
,将list_1[key_id]
的每次使用替换为键,将list_2[key_id]
替换为值。
keys = [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2]
values = ['x','x','x','y','g','r','t','w','r','r','r','t','f','c','d']
result = {}
for key,value in zip(keys,values):
if key not in result:
result[key] = []
if value not in result[key]:
result[key].append(value)
else:
if value not in result[key]:
result[key].append(value)
print(result)
zip(keys,values) this will create a iterable of tuples, each tuple consist of one element from the keys and values.
(1,'x')
(1,'x')