Как избежать просмотра словаря дважды для получения / установки значения ключа в Python? - PullRequest
3 голосов
/ 10 марта 2020

У меня есть список:

lst = [('a', 1), ('b', 2), ('c', 3), ('a', 4), ('c', 5)]

, и я хочу сгруппировать по первому элементу кортежа и добавить второй элемент:

group = {'a': [1, 4], 'b': [2], 'c': [3, 5]}

Итак, мой код выглядит следующим образом :

group = dict()
for e1, e2 in lst:
    if e1 in group:
        group[e1].append(e2)
    else:
        group[e1] = [e2]

Что мне не нравится в этом коде, так это то, что я дважды ищу ключ в словаре группы, один для команды e1 in group и два для команды group[e1] = ...

Есть ли лучший способ сохранить «указатель», если ключ найден, и не нужно искать второй раз, чтобы установить значение этого ключа?
Кроме того, если есть гораздо лучший Решение с использованием библиотеки, пожалуйста, дайте мне знать.

Ответы [ 6 ]

4 голосов
/ 10 марта 2020

Вы можете использовать defaultdict.

from collections import defaultdict
lst = [('a', 1), ('b', 2), ('c', 3), ('a', 4), ('c', 5)]
group=defaultdict(list)

for k,v in lst:
    group[k].append(v)

group
# defaultdict(list, {'a': [1, 4], 'b': [2], 'c': [3, 5]})
3 голосов
/ 10 марта 2020

Вы можете использовать get() со значением по умолчанию пустой список []

group = {}
for e1, e2 in lst:
    group[e1] = group.get(e1, []) + [e2]
2 голосов
/ 10 марта 2020

Использование collections.defaultdict:

from collections import defaultdict

group = defaultdict(list)

for e1, e2 in lst:
    group[e1].append(e2)
2 голосов
/ 10 марта 2020

Вы можете использовать defaultdict .

Когда каждый ключ встречается в первый раз, он еще не находится в отображении; поэтому запись создается автоматически с помощью функции default_factory, которая возвращает пустой список. Затем операция list.append () присоединяет значение к новому списку.

from collections import defaultdict
group = defaultdict(list)
for e1, e2 in lst:
    group[e1].append(e2)
1 голос
/ 10 марта 2020

Вы делаете с groupby,

In [38]: from itertools import groupby
In [39]: {g:[i[1]for i in l] for g, l in groupby(sorted(lst),lambda x:x[0])}
Out[39]: {'a': [1, 4], 'b': [2], 'c': [3, 5]}
0 голосов
/ 10 марта 2020

Вы, вероятно, можете сделать это следующим образом:


lst = [('a', 1), ('b', 2), ('c', 3), ('a', 4), ('c', 5)]

group = {}

for key, value in lst:
      group.setdefault(key, []).append(value)

...