1
votes

Comment convertir une liste de tuples en dictée

J'ai une liste de tuples comme so qui ne sont pas classés comme indiqué ici en raison du fait que le fichier texte d'entrée n'est pas ordonné en premier lieu.

<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>

et je voudrais le convertir en

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))

Je commence avec un fichier texte où j'ai chaque tuple dans une ligne sous forme de chaînes - non ordonné:

a w 14
b w 9
x a 7
...


0 commentaires

5 Réponses :


0
votes

Vous pouvez le faire en utilisant defaultdict de collections comme,

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


0 commentaires

0
votes

C'est un bon cas pour utiliser defaultdict depuis le module collections.

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 commentaires

1
votes

Utilisation de 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 commentaires

1
votes

Si vous ne voulez rien utiliser en dehors de la boîte, vous pouvez simplement essayer:

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


0 commentaires

0
votes

Je pense que la solution la plus simple serait

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

Cela donnera le dict que vous voulez.

new_dict = {i[0]: {j[1]:j[2] for j in g if j[0]==i[0]} for i in g}


0 commentaires