【问题标题】:How to separate a list into dictionary based on first and second values [duplicate]如何根据第一个和第二个值将列表分成字典[重复]
【发布时间】:2017-03-01 20:04:29
【问题描述】:

我不确定如何准确地表达我的问题,所以我将在这里更深入地介绍。

我正在尝试使用以下列表的输入在 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']}

非常感谢任何帮助!谢谢:)

【问题讨论】:

  • 元组是否有序?
  • 不,他们不必如此。它们只是用来区分哪些边彼此相邻。
  • 如果顺序无关紧要,在字典中使用sets 而不是lists 是最简单的。

标签: python dictionary graph-coloring


【解决方案1】:

直截了当,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']}

或者,如果您愿意,可以使用默认字典:

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%。 (见this repl.it comparison

【讨论】:

  • 谢谢!绝对是我正在寻找的正确的东西:)
  • 这并不是完全错误,但我很少看到 EAFP 应用于 dict 成员资格。 defaultdict 是解决这个问题的惯用方法,或者 setdefault 在 python 版本上为时过早,无法使用 defaultdict
  • @PeterDeGlopper 我添加了该选项,因为它在所有情况下都更快。除非我需要额外的速度,否则我倾向于不导入 defaultdict,但是 YMMV。
【解决方案2】:
>>> 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

【讨论】:

  • 这接近正确,但不会创建互惠关系 - OP 的示例显示 'B': ['A', 'C'] 尽管没有明确的 ('B', 'A') 元组,因为有一个 ('A', 'B') 元组。另外,我会使用collections.defaultdict(list) - 或者更好的defaultdict(set),因为顺序无关紧要。
【解决方案3】:

为什么不创建一个列表,然后将每个元素都添加到其中?

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']}

【讨论】:

  • 这对我来说是一个好的开始,但我真正想要的是让每个 Key 将其邻居显示为 key,例如{'A': ['B','C','D'], 'B': ['A','C'], 'C': ['A','B','D'], 'D': ['A','C']}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 2017-05-23
  • 1970-01-01
  • 2021-03-09
  • 2020-04-08
相关资源
最近更新 更多