[英]How to convert a list of tuples to a dict of dicts
我有一個像這樣的元組列表,由於未將輸入文本文件排在第一位,因此未按此處所示進行排序。
g = [('a', 'w', 14), ('a', 'x', 7), ('a', 'y', 9),
('b', 'w', 9), ('b', 'z', 6),
('w', 'a', 14), ('w', 'b', 9), ('w', 'y', 2),
('x', 'a', 7), ('x', 'y', 10), ('x', 'x', 15),
('y', 'a', 9), ('y', 'w', 2), ('y', 'x', 10), ('y', 'z', 11),
('z', 'b', 6), ('z', 'x', 15), ('z', 'y', 11)]
並希望將其轉換為
g = {
'a': {'w': 14, 'x': 7, 'y': 9},
'b': {'w': 9, 'z': 6},
'w': {'a': 14, 'b': 9, 'y': 2},
'x': {'a': 7, 'y': 10, 'z': 15},
'y': {'a': 9, 'w': 2, 'x': 10, 'z': 11},
'z': {'b': 6, 'x': 15, 'y': 11},
}
我從一個文本文件開始,其中一行中的每個元組都作為字符串-未排序:
a w 14
b w 9
x a 7
...
要獲取元組列表:當前具有以下代碼:
with open(filename, 'r') as reader:
num_nodes = int(reader.readline())
edges = []
for line in islice(reader, num_nodes + 1, None):
values = line.split()
values[2] = int(values[2])
edges.append(tuple(values))
文本文件具有以下格式:
<number of nodes>
<ID of node>
...
<ID of node>
<number of edges>
<from node ID> <to node ID> <distance>
...
<from node ID> <to node ID> <distance>
任何幫助/建議都將受到高度贊賞。
使用itertools.groupby
:
from itertools import groupby
from operator import itemgetter
g_dict = {k: dict(x[1:] for x in grp) for k, grp in groupby(sorted(g), itemgetter(0))}
print(g_dict)
#{'a': {'w': 14, 'x': 7, 'y': 9},
# 'b': {'w': 9, 'z': 6},
# 'w': {'a': 14, 'b': 9, 'y': 2},
# 'x': {'a': 7, 'x': 15, 'y': 10},
# 'y': {'a': 9, 'w': 2, 'x': 10, 'z': 11},
# 'z': {'b': 6, 'x': 15, 'y': 11}}
如果您不想在盒子外面使用任何東西,可以嘗試:
g = [('a', 'w', 14), ('a', 'x', 7), ('a', 'y', 9),
('b', 'w', 9), ('b', 'z', 6),
('w', 'a', 14), ('w', 'b', 9), ('w', 'y', 2),
('x', 'a', 7), ('x', 'y', 10), ('x', 'x', 15),
('y', 'a', 9), ('y', 'w', 2), ('y', 'x', 10), ('y', 'z', 11),
('z', 'b', 6), ('z', 'x', 15), ('z', 'y', 11)]
g_dict = {}
# Go through your list of tuples
for element in g:
# Check if we should create a new key or not
if not element[0] in g_dict.keys():
# Create a new key
g_dict[element[0]] = {}
# Check if we need to make a new key or not for the inner dict
if not element[1] in g_dict[element[0]].keys():
g_dict[element[0]][element[1]] = element[2]
else:
if not element[1] in g_dict[element[0]].keys():
g_dict[element[0]][element[1]] = element[2]
print g_dict
您可以使用defaultdict
collections
例如,
>>> g
[('a', 'w', 14), ('a', 'x', 7), ('a', 'y', 9), ('b', 'w', 9), ('b', 'z', 6), ('w', 'a', 14), ('w', 'b', 9), ('w', 'y', 2), ('x', 'a', 7), ('x', 'y', 10), ('x', 'x', 15), ('y', 'a', 9), ('y', 'w', 2), ('y', 'x', 10), ('y', 'z', 11), ('z', 'b', 6), ('z', 'x', 15), ('z', 'y', 11)]
>>> from collections import defaultdict
>>> d = defaultdict(dict)
>>>
>>> for item in g:
... a, b, c = item
... d[a].update({b: c})
...
>>> import pprint
>>> pprint.pprint(dict(d))
{'a': {'w': 14, 'x': 7, 'y': 9},
'b': {'w': 9, 'z': 6},
'w': {'a': 14, 'b': 9, 'y': 2},
'x': {'a': 7, 'x': 15, 'y': 10},
'y': {'a': 9, 'w': 2, 'x': 10, 'z': 11},
'z': {'b': 6, 'x': 15, 'y': 11}}
這是在collections模塊中使用defaultdict的一個好案例。
from collections import defaultdict
g = [('a', 'w', 14), ('a', 'x', 7), ('a', 'y', 9),
('b', 'w', 9), ('b', 'z', 6),
('w', 'a', 14), ('w', 'b', 9), ('w', 'y', 2),
('x', 'a', 7), ('x', 'y', 10), ('x', 'x', 15),
('y', 'a', 9), ('y', 'w', 2), ('y', 'x', 10), ('y', 'z', 11),
('z', 'b', 6), ('z', 'x', 15), ('z', 'y', 11)]
d = defaultdict(dict)
for k1, k2, v in g:
d[k1].setdefault(k2, v)
d
# returns:
defaultdict(dict,
{'a': {'w': 14, 'x': 7, 'y': 9},
'b': {'w': 9, 'z': 6},
'w': {'a': 14, 'b': 9, 'y': 2},
'x': {'a': 7, 'x': 15, 'y': 10},
'y': {'a': 9, 'w': 2, 'x': 10, 'z': 11},
'z': {'b': 6, 'x': 15, 'y': 11}})
我認為最簡單的解決方案是
new_dict = {i[0]: {j[1]:j[2] for j in g if j[0]==i[0]} for i in g}
這將導致您想要的字典。
new_dict = {'x': {'y': 10, 'a': 7, 'x': 15}, 'z': {'b': 6, 'y': 11, 'x': 15}, 'y': {'w': 2, 'a': 9, 'x': 10, 'z': 11}, 'b': {'w': 9, 'z':6}, 'w': {'b': 9, 'y': 2, 'a': 14}, 'a': {'w': 14, 'x': 7, 'y': 9}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.