web-dev-qa-db-fra.com

Convertir une clé de chaîne en int dans un dictionnaire

Ma question est très similaire à celle-ci , sauf que j'ai un dictionnaire de listes et je suis intéressé à changer à la fois la valeur de la clé et tous les éléments dans chaque forme de liste string à int.

Donc, par exemple, je voudrais le dictionnaire:

{ '1':['1', '2', '3', '4'] , '2':['1', '4'] , '3':['43','176'] }

devenir:

{ 1:[1, 2, 3, 4] , 2:[1, 4] , 3:[43,176] }

Est-ce possible?

Plus généralement car j'ai créé ce dictionnaire à partir d'un fichier au format JSON

{"0": ["1", "2", "3", "4"], "1": ["0", "2", "3", "4", "27", "94 "," 95 "," 97 "," 128 "," 217 "," 218 "," 317 "]," 2 ": [" 0 "," 1 "," 3 "," 4 "," 94 "," 95 "]," 3 ": [" 0 "," 1 "," 2 "," 4 "," 377 "]," 4 ": [" 0 "," 1 "," 2 ", "3", "27", "28"], "5": ["6", "7", "8"], "6": ["5", "7", "8"], " 7 ": [" 5 "," 6 "," 8 "," 14 "," 23 "," 40 "," 74 "," 75 "," 76 "," 362 "," 371 "," 372 "]," 8 ": [" 5 "," 6 "," 7 "," 66 "]," 9 ": [" 10 "," 11 "," 12 "]," 10 ": [" 9 "," 11 "," 12 "," 56 "," 130 "," 131 "]}

avec les instructions suivantes:

json_data = open("coauthorshipGraph.txt")
coautorshipDictionary = json.load( json_data )
json_data.close()

existe-t-il un moyen de le faire directement au moment du chargement?

30
Matteo
d = {'1':'145' , '2':'254' , '3':'43'}
d = {int(k):int(v) for k,v in d.items()}
>>> d
{1: 145, 2: 254, 3: 43}

pour les listes de valeurs

>>> d = { '1':['1', '2', '3', '4'] , '2':['1', '4'] , '3':['43','176'] }
>>> d = {int(k):[int(i) for i in v] for k,v in d.items()}

dans ton cas:

coautorshipDictionary = {int(k):int(v) for k,v in json.load(json_data)}

ou

coautorshipDictionary = {
    int(k):[int(i) for i in v] for k,v in json.load(json_data)}
47
ndpu

Similaire à la réponse de Decency, mais en tirant parti de l'argument object_hook:

coautorshipDictionary = json.load(json_data, object_hook=lambda d: {int(k): [int(i) for i in v] if isinstance(v, list) else v for k, v in d.items()}) # iteritems() for Python 2

Le principal avantage de cette méthode est que, si vous vous retrouvez avec des dict imbriqués, le chargeur gérera chaque dict imbriqué de lui-même car il charge les données sans que vous ayez à écrire du code pour parcourir votre dict résultant. Vous pouvez également ajouter des vérifications pour les cas où les valeurs dans les listes ne sont pas des chaînes numériques ou si les listes elles-mêmes contiennent également des dictés, si votre structure JSON devient plus compliquée et si vos données auront uniquement des listes comme valeurs pour votre dict de niveau supérieur. vous pouvez supprimer la partie if isinstance(v, list) else v.

4
JAB

Cette solution fonctionnera dans le cas où vous avez un itérable comme valeur, comme dans le json que vous avez fourni.

my_dict = {"0": ["1", "2", "3", "4"], "1": ["0", "2", "3", "4", "27", "94", "95", "97", "128", "217", "218", "317"], "2": ["0", "1", "3", "4", "94", "95"], "3": ["0", "1", "2", "4", "377"], "4": ["0", "1", "2", "3", "27", "28"], "5": ["6", "7", "8"], "6": ["5", "7", "8"], "7": ["5", "6", "8", "14", "23", "40", "74", "75", "76", "362", "371", "372"], "8": ["5", "6", "7", "66"], "9": ["10", "11", "12"], "10": ["9", "11", "12", "56", "130", "131"]}

output_dict = {}
for key, value in my_dict.iteritems():
    output_dict[int(key)] = [int(item) for item in value]

output_dict

Sortie:

{0: [1, 2, 3, 4],
 1: [0, 2, 3, 4, 27, 94, 95, 97, 128, 217, 218, 317],
 2: [0, 1, 3, 4, 94, 95],
 3: [0, 1, 2, 4, 377],
 4: [0, 1, 2, 3, 27, 28],
 5: [6, 7, 8],
 6: [5, 7, 8],
 7: [5, 6, 8, 14, 23, 40, 74, 75, 76, 362, 371, 372],
 8: [5, 6, 7, 66],
 9: [10, 11, 12],
 10: [9, 11, 12, 56, 130, 131]}

Pour la deuxième partie de la question, vous pouvez utiliser une compréhension de dict en ligne pendant que vous lisez le fichier. C'est obscur comme l'enfer.

with open('coauthorshipGraph.txt', 'r') as f:
    json_data = { int(key) : [int(item) for item in value] for key, value in json.load(f).iteritems()}

json_data

Cela donne le même résultat que ci-dessus.

3
Chris Arena