Как преобразовать список кортежей в диктовку - PullRequest
1 голос
/ 14 мая 2019

У меня есть список таких кортежей, которые не упорядочены, как показано здесь, из-за того, что исходный текстовый файл не упорядочен в первую очередь.

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>

Любая помощь / совет высоко ценится.

Ответы [ 5 ]

1 голос
/ 14 мая 2019

Если вы не хотите использовать что-либо вне коробки, вы можете просто попробовать:

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
1 голос
/ 14 мая 2019

Использование 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}}
0 голосов
/ 14 мая 2019

Я думаю, что самым простым решением было бы

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}}
0 голосов
/ 14 мая 2019

Это хороший пример использования 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}})
0 голосов
/ 14 мая 2019

Вы можете сделать это, используя 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}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...