Создание словаря со списками в качестве значений с использованием понимания списков

Я пытаюсь упростить следующий код, используя понимание списка/слова, в котором я хочу создать словарь списков из списка.

В этом примере я беру мод (или любую другую функцию) каждого предмета в качестве ключа. Если ключ не существует в словаре, создается новый список, и элемент добавляется к списку, в противном случае элемент добавляется напрямую.

def get_key(val):
    return val % 3 # Can be something else, it doesn't matter


dict = {}
data = [i for i in range(10)]
for item in data:
    key = get_key(item)
    if key in dict:
        dict[key].append(item)
    else:
        dict[key] = [item]
print(dict)

Ожидаемый результат

{0: [0, 3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]}

Чтобы упростить приведенный выше код, я попробовал этот уродливый подход:

for item in data:
    key = get_key(item)
    dict[key] = [item] if key not in dict else (dict[key], dict[key].append(item))[0]

Однако как добиться того же без цикла for, используя понимание списка/слова как одно выражение?

Я мог бы придумать что-то подобное, но он не может добавить значение в уже существующий список.

{get_key(item):[item] for item in data}

Похожие сообщения:

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
633
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вам действительно не нужно понимание списка/слова здесь. Просто используйте обычный цикл с defaultdict:

out = collections.defaultdict(list)
for i in range(10):
    out[i % 3].append(i)

Спасибо за ваш ответ. Практически это работает, но я ищу решение для одного выражения, использующее понимание списка/слова.

PIG208 11.12.2020 12:39

Вы близки. ниже мой подход к использованию понимания dict

data = list(range(0,10))
mod= 3
{i:data[i::mod] for i in range(mod)}

Вне

{0: [0, 3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]}

Спасибо. Этот метод хорошо работает для данных списка возрастающих последовательных целых чисел в случае, если ключ определяется по модулю. Но его нельзя обобщить на другие случаи, когда ключ определяется другими правилами. Я обновил свой вопрос, чтобы сделать его более понятным.

PIG208 11.12.2020 13:32

Попробуйте словарь по умолчанию,

from collections import defaultdict

d = defaultdict(list)
for item in range(10): 
    d[item % 3].append(item)
Ответ принят как подходящий

Создайте список значений, где первым элементом каждого подсписка будет ключ, который равен [n] +, а затем используйте его для создания словаря.

m = [[n] + [i[1] for i in [(x%3,x) for x in range(10)]if i[0] == n] for n in range(3)]

dictt = {i[0]:i[1:] for i in m}
print(dictt)

>>> {0: [0, 3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]}

Все на одной линии

dictt = {i[0]:i[1:] for i in [[n] + [i[1] for i in [(x%3,x) for x in range(10)]if i[0] == n] for n in range(3)]}

Другие вопросы по теме