[英]Python dictionary with multiple unique values corresponding to a key
I have 2 lists which correspond to what I would like to be my key:value pairs, for example:我有 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)
I've (kind of) been able to create a dictionary via: dict = dict(zip(list_1, [list_2]))
我已经(有点)能够通过以下方式创建字典:
dict = dict(zip(list_1, [list_2]))
However the problem with this is that it is only picking up '1' as a key and also results in duplicate entries within the list of values for the key.然而,这样做的问题是它只选择“1”作为键,并且还会导致键值列表中出现重复条目。
Can anyone suggest a way to create a dictionary so that only the unique values from list_2
are mapped to their corresponding key?任何人都可以建议一种创建字典的方法,以便仅将
list_2
中的唯一值映射到其相应的键吗?
Thanks谢谢
EDIT:编辑:
output I'm looking for would be one dictionary keyed by 1 and 2 with lists as values containing only the unique values for each ie:我正在寻找的输出将是一个由 1 和 2 键控的字典,其中列表作为值仅包含每个值的唯一值,即:
dict = {1: [x,y,g,r,t,w], 2: [r,t,f,c,d]}
Since a dictionary is a set it cant contain twice the same key but it can have the key once then a list of value for that you can use the one-line method由于字典是一个集合,它不能包含两次相同的键,但它可以有一次键,然后是一个值列表,您可以使用单行方法
my_dict = {key:[list_2[i] for i in range(len(list_2)) if list_1[i]==key] for key in set(list_1)}
Or a more classic method或者更经典的方法
my_dict = {}
for key_id in range(len(list_1)):
if list_1[key_id] not in my_dict:
my_dict[list_1[key_id]] = []
my_dict[list_1[key_id]].append(list_2[key_id])
In both case the result is在这两种情况下,结果都是
my_dict = {1: ['x', 'x', 'x', 'y', 'g', 'r', 't', 'w', 'r'], 2: ['r', 'r', 't', 'f', 'c', 'd']}
This sort of problem is properly solved with a collections.defaultdict(set)
;使用
collections.defaultdict(set)
可以正确解决此类问题; the defaultdict
gives you easy auto-vivificaction of set
s for each key on demand, and the set
uniquifies the values associated with each key: defaultdict
根据需要为每个键提供了简单的set
s 自动激活,并且该set
统一了与每个键关联的值:
from collections import defaultdict
mydict = defaultdict(set)
for k, v in zip(list_1, list_2):
mydict[k].add(v)
You can then convert the result to a plain dict
with list
values with:然后,您可以将结果转换为带有
list
值的普通dict
:
mydict = {k: list(v) for k, v in mydict.items()}
If order of the values must be preserved, on modern Python you can use dict
s instead of set
(on older Python, you'd use collections.OrderedDict
):如果必须保留值的顺序,在现代 Python 上,您可以使用
dict
s 而不是set
(在较旧的 Python 上,您将使用collections.OrderedDict
):
mydict = defaultdict(dict)
for k, v in zip(list_1, list_2):
mydict[k][v] = True # Dummy value; we're using a dict to get an ordered set of the keys
with the conversion to plain dict
with list
values being unchanged转换为普通
dict
, list
值不变
If the input is already sorted, itertools.groupby
is theoretically slightly more efficient (it's actual O(n)
, vs. average case O(n)
using dict
s), but in practice the defaultdict
is typically as faster or faster (the implementation of groupby
has some unavoidable inefficiencies).如果输入已经排序,
itertools.groupby
理论上稍微更有效(它是实际的O(n)
,与使用dict
s 的平均情况O(n)
),但实际上defaultdict
通常更快或更快(实现groupby
有一些不可避免的低效率)。 Just for illustration, the groupby
solution would be:仅用于说明,
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))]
The problem is your key is too unique.问题是您的密钥太独特了。 there're only two unique keys 1 and 2. So if you're creating dictionaries you can't have {1:x, 1:y} at same time for example, unless you change the key to something new and unique.
只有两个唯一键 1 和 2。因此,如果您正在创建字典,则不能同时拥有 {1:x, 1:y} ,除非您将键更改为新的和唯一的。
I would use a tuple in your purpose:我会在你的目的中使用一个元组:
list(set(tuple(zip(list_1, list_2))))
The set gives you unique mappings which is what dropping the duplicates.该集合为您提供了独特的映射,这就是删除重复项的原因。
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)
{1: ['x', 'y', 'g', 'r', 't', 'w'], 2: ['r', 't', 'f', 'c', 'd']}
{1: ['x', 'y', 'g', 'r', 't', 'w'], 2: ['r', 't', 'f', 'c', 'd ']}
Note:笔记:
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')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.