简体   繁体   English

具有与键对应的多个唯一值的 Python 字典

[英]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转换为普通dictlist值不变

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM