Как обрабатывать несколько ключей для словаря в Python? - PullRequest
0 голосов
/ 29 мая 2018

Я искал, как добавить несколько val для отдельных ключей в Dict, если найден повторяющийся ключ.

Давайте рассмотрим пример:

list_1 = ['4', '6' ,'8', '8']
list_2 = ['a', 'b', 'c', 'd']
new_dict = dict(zip(list_1,list_2))
...output...
{'8': 'd', '4': 'a', '6': 'b'}

Ожидаетсяoutput:

{'8': 'c,d', '4': 'a', '6': 'b'}

Чтобы обработать два приведенных выше списка и объединить их в один dict, я столкнулся с определенной проблемой, заключающейся в том, что у нас не может быть двух восьмерок в «ключе» dict, которыйповедение по умолчанию, и я понимаю, почему!

Некоторые из вариантов, которые существуют для обработки такого сценария:

1) Найти, если «ключ» уже существует в dict, если да, то добавить новый val к ​​«ключу»

2) Создайте изменяемый объект для ссылки на каждый ключ, и таким образом вы можете иметь несколько дуплексных ключей ~~ Не совсем мой вариант использования

Итак, как я могу получить ожидаемый результат, используя опцию #1?

Ответы [ 3 ]

0 голосов
/ 29 мая 2018

Вы можете сделать это с помощью цикла for, который перебирает два списка:

list_1 = ['4', '6' ,'8', '8']
list_2 = ['a', 'b', 'c', 'd']

new_dict = {}
for k, v in zip(list_1, list_2):
    if k in new_dict:
        new_dict[k] += ', ' + v
    else:
        new_dict[k] = v

Могут быть проблемы с эффективностью для больших словарей, но в простых случаях он будет работать просто отлично.

Благодаря @ Ев.Kounis и @bruno desthuilliers, которые указали на несколько улучшений исходного ответа.


Ответ coldspeed более эффективен, чем мой, я держу его здесь, потому что он все еще правильный, и я не вижупункт в его удалении.

0 голосов
/ 29 мая 2018

Попробуйте использовать setdefault словарную функцию и получите ее индекс, затем используйте try и, за исключением проверки, существует ли idx или нет, я не получал индекс элемента каждый разпотому что есть дубликаты, и в конце я форматирую его так, чтобы он выводил как Ваш желаемый вывод:

new_dict = {}
list_1 = ['4', '6' ,'8', '8']
list_2 = ['a', 'b', 'c', 'd']
for i in list_1:
   try:
      idx+=1
   except:
      idx = list_1.index(i)
   new_dict.setdefault(i, []).append(list_2[idx])
print({k:', '.join(v) for k,v in new_dict.items()})

Вывод:

{'4': 'a', '6': 'b', '8': 'c, d'}
0 голосов
/ 29 мая 2018

defaultdict / dict.setdefault

Давайте перейдем к нему:

  1. Последовательное итерирование по элементам
  2. Добавление строковых значений, принадлежащих одному и тому же ключу
  3. После этого переберите каждую пару ключ-значение и соедините все вместе для получения окончательного результата.

from collections import defaultdict

d = defaultdict(list)   
for i, j in zip(list_1, list_2):
    d[i].append(j)

defaultdict делает вещи простыми, иэффективен с добавлением.Если вы не хотите использовать defaultdict, используйте вместо этого dict.setdefault (но это немного неэффективно):

d = {}
for i, j in zip(list_1, list_2):
    d.setdefault(i, []).append(j)

new_dict = {k : ','.join(v) for k, v in d.items()})
print(new_dict)
{'4': 'a', '6': 'b', '8': 'c,d'}

PandasDataFrame.groupby + agg

Если вам нужна производительность на больших объемах, попробуйте использовать pandas:

import pandas as pd

df = pd.DataFrame({'A' : list_1, 'B' : list_2})
new_dict = df.groupby('A').B.agg(','.join).to_dict()

print(new_dict)
{'4': 'a', '6': 'b', '8': 'c,d'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...