Создать словарь с длиной элементов в списке в качестве ключей - PullRequest
1 голос
/ 24 июня 2019

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

combination = [('A',), ('B',), ('C',), ('D',), ('A', 'B'), ('A','C'),
 ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('A', 'B', 'C'), 
('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D'),('A', 'B', 'C', 'D')]

Я пытался temp_dict = {len(i): i for i in combinations}

Желаемый результат:

{1: [('A',), ('B',), ('C',), ('D',)], 2: [('A', 'B'), ('A','C'),
 ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')], 3: [('A', 'B', 'C'), 
('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')], 4: [('A', 'B', 'C', 'D')]}```

Ответы [ 4 ]

6 голосов
/ 24 июня 2019

Вы можете попробовать словарь с пониманием списка внутри него

temp_dict = {len(i): [x for x in combination if len(x) == len(i)] for i in combination}
print(temp_dict)

Или вы можете использовать setdefault:

temp_dict = {}
for i in combination:
    temp_dict.setdefault(len(i), []).append(i)
print(temp_dict)

Оба Вывод:

{1: [('A',), ('B',), ('C',), ('D',)], 2: [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')], 3: [('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')], 4: [('A', 'B', 'C', 'D')]}
2 голосов
/ 24 июня 2019

Ваш текущий подход {len(i): i for i in combination} фактически выбирает последний кортеж определенной длины и добавляет его в словарь, а это не то, что вам нужно, вместо этого вам нужен список всех таких кортежей.

Вы можетеиспользуйте collection.defaultdict для создания набора списков в качестве значений.Затем вы можете перебрать список и добавить кортежи одинаковой длины к ключу

from collections import defaultdict

res = defaultdict(list)

#Iterate over the list
for item in combination:
    #Append tuples with same length to same value list
    res[len(item)].append(item)

print(dict(res))

Выходные данные будут

{1: [('A',), ('B',), ('C',), ('D',)], 
2: [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')], 
3: [('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')], 
4: [('A', 'B', 'C', 'D')]}
1 голос
/ 24 июня 2019

Еще один выстрел в это через itertools.groupby:

>>> from itertools import groupby
>>> dict([(cnt, list(l)) for cnt, l in groupby(combinations, len)])
{1: [('A',), ('B',), ('C',), ('D',)], 2: [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')], 3: [('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')], 4: [('A', 'B', 'C', 'D')]}
1 голос
/ 24 июня 2019

Другой подход заключается в использовании itertools.groupby.Обратите внимание, что groupby предполагает, что ваши данные отсортированы .

from itertools import groupby

{k: list(g) for k, g in groupby(combination, key=len)}

Вывод:

{1: [('A',), ('B',), ('C',), ('D',)],
 2: [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')],
 3: [('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')],
 4: [('A', 'B', 'C', 'D')]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...