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 ...
5 Réponses :
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}}
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}})
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}}
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
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}