Python словарь с несколькими уникальными значениями, соответствующими ключу - PullRequest
2 голосов
/ 31 января 2020

У меня есть 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(list_1, [list_2]))

Однако проблема в том, что он выбирает только «1» в качестве ключа, а также приводит к дублированию записей в списке значений для ключа.

Может кто-нибудь предложить способ создать словарь так, чтобы только уникальные значения из list_2 были сопоставлены с их соответствующими ключами?

Спасибо

РЕДАКТИРОВАТЬ:

вывод Я ищу будет один словарь с ключами 1 и 2 со списками в качестве значений, содержащих только уникальные значения для каждого, то есть:

dict = {1: [x,y,g,r,t,w], 2: [r,t,f,c,d]}

Ответы [ 4 ]

1 голос
/ 31 января 2020

Поскольку словарь является набором, он не может содержать дважды один и тот же ключ, но он может иметь ключ один раз, а затем список значений, для которого вы можете использовать однострочный метод

my_dict = {key:[list_2[i] for i in range(len(list_2)) if list_1[i]==key] for key in set(list_1)}

Или более classi c 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])

В обоих случаях результат равен

my_dict = {1: ['x', 'x', 'x', 'y', 'g', 'r', 't', 'w', 'r'], 2: ['r', 'r', 't', 'f', 'c', 'd']}
1 голос
/ 31 января 2020

Эта проблема правильно решается с помощью collections.defaultdict(set); defaultdict дает вам простое автоматическое оживление set с для каждого ключа по требованию, а set унифицирует значения, связанные с каждым ключом:

from collections import defaultdict

mydict = defaultdict(set)
for k, v in zip(list_1, list_2):
    mydict[k].add(v)

Затем вы можете преобразовать результат в обычный dict с list значениями с:

mydict = {k: list(v) for k, v in mydict.items()}

Если порядок значений должен быть сохранен, в современных 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 

с преобразованием в обычный dict с неизменными значениями list

Если вход уже отсортирован, itertools.groupby теоретически немного более эффективен (это факт O(n), в сравнении со средним случаем O(n) с использованием dict с), но на практике 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))]
0 голосов
/ 31 января 2020
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 ']}

Примечание:

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')
0 голосов
/ 31 января 2020

Проблема в том, что ваш ключ слишком уникален. есть только два уникальных ключа 1 и 2. Поэтому, если вы создаете словари, у вас не может быть, например, {1: x, 1: y} одновременно, если вы не измените ключ на что-то новое и уникальное.

Я бы использовал кортеж в вашей цели:

list(set(tuple(zip(list_1, list_2))))

Набор дает вам уникальные сопоставления, которые позволяют отбрасывать дубликаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...