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

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

То, что я пытаюсь сделать, это выполнить задачу Color Coloring в Python, используя ввод списка, такого как этот:

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

Это означает "соседей" каждого ребра графа, так что A является соседом B C и D, B является соседом C, а C является соседом D

Теперь, что я пытаюсь сделать, это разбить их на ключи в словаре, как это:

neighbors = {}
neighbors['A'] = ['B', 'C', 'D']
neighbors['B'] = ['A', 'C']
neighbors['C'] = ['A', 'B', 'D']
neighbors['D'] = ['A', 'C']

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

neighbours = {}
myList = [('A','B'),('A','C'),('A','D'),('B','C'),('C','D')]
for i in myList:
    neighbours[i[0]] = (i[1])

print(neighbours)

Это обеспечивает вывод:

{'A': 'D', 'C': 'D', 'B': 'C'}

Но я бы хотел, чтобы это выглядело так:

{'A': ['B','C','D'], 'B': ['A','C'], 'C': ['A','B','D'], 'D': ['A','C']}

Любая помощь очень ценится! Спасибо:)

3 ответа

Решение

Прямой подход EAFP:

adj = [('A','B'),('A','C'),('A','D'),('B','C'),('C','D')]
mat = {}
for (x, y) in adj:
    try:
        mat[x].append(y)
    except KeyError:
        mat[x] = [y]
    try:
        mat[y].append(x)
    except KeyError:
        mat[y] = [x]

>>> mat
{'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['A', 'C'], 'D': ['A', 'C']}

Или, если вы предпочитаете, по умолчанию dict:

from collections import defaultdict
default = defaultdict(list)
for (x, y) in adj:
    default[x].append(y)
    default[y].append(x)

>>> default
defaultdict(<type 'list'>, {'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['A', 'C'], 'D': ['A', 'C']})

Что на 10-20% быстрее, если вы заинтересованы в производительности. (см. это сравнение repl.it)

>>> l = [('A','B'),('A','C'),('A','D'),('B','C'),('C','D')]
>>> 
>>> d = {}
>>> for i in l:
...     temp = d.get(i[0], [])
...     temp.append(i[1])
...     d[i[0]] = temp

Почему бы не создать список и не добавить в него каждый элемент?

neighbours = {}
myList = [('A','B'),('A','C'),('A','D'),('B','C'),('C','D')]
for i in myList:
    if i[0] not in neighbours:
        neighbours[i[0]]= list()
    neighbours[i[0]].append(i[1])

print(neighbours)

Изменить: результаты в:

{'B': ['C'], 'A': ['B', 'C', 'D'], 'C': ['D']}
Другие вопросы по тегам