2014-01-17 2 views
13

Мой вопрос очень похож на this one, за исключением того, что у меня есть словарь списков, и меня интересует изменение как значения ключа, так и всех элементов в каждой форме списка string до int.Преобразование строкового ключа в int в словаре

Так, например, я хотел бы словарь:

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

стать:

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

Возможно ли это?

Больше в целом, так как я создал этот словарь из файла формата 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 "," 1 2" , "56", "130", "131"]}

со следующими инструкциями:

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

есть способ сделать это непосредственно во время загрузки?

+1

Обратите внимание, что 'int (item)' вызывает ошибку, если 'item' не может быть преобразован в int. Очень важно обернуть это блоком 'try .. except', так как вы читаете из файла, что может иметь некоторые неожиданные значения. – vikki

+0

@vikki - thks для указание. Хотя я все еще новичок и еще не получил часть учебника по исключениям, я буду замечен: D – Matteo

ответ

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

для списков значений

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

в вашем случае:

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

или

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

Не будет работать для d = {'1': ['2', '3']} ... его значения - это списки. –

+0

Мой пример не согласуется с данными JSON, загруженными мной. На самом деле каждый элемент словаря - это список, а не один int. Любые изменения, которые я должен сделать с вашим предложением? – Matteo

+0

По какой-то причине 'coautorshipDictionary = {int (k): int (v) для k, v в json.load (json_data)}' не работает для меня. JSON был загружен, но значения не были преобразованы в INT. 'd = {int (k): int (v) для k, v в d.items()}', однако, отлично работает, поэтому я просто загрузил JSON и затем преобразован в INT на втором шаге. Странный. –

2

Это решение будет работать в случае, когда у вас есть итератор, как ваше значение, как в json, который вы предоставили.

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 

Выход:

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

Для второй части вопроса, то вы можете использовать Dict понимание в строке, как вы читаете файл. Тем не менее, он запутан как ад.

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 

Это дает тот же результат, что и выше.

+0

Большое спасибо за ваш ответ, он отлично работает. Вы знаете, есть ли способ сделать это непосредственно при загрузке данных? – Matteo

+0

Конечно, но это некрасиво. –

2

Подобный ответ порядочности, но пользуясь 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 

Основное преимущество этого метода состоит в том, что, если вы когда-нибудь в конечном итоге с любой вложенной dicts, загрузчик будет обрабатывать каждый вложенный Dict самостоятельно, поскольку он загружает данные без необходимости писать код для прохождения вашего результата dict.Вы также можете добавить проверки для случаев, когда значения в списках не являются числовыми строками, а сами списки содержат также dicts, если ваша структура JSON становится более сложной, и если ваши данные будут иметь только списки в качестве значений для вашего верхнего уровня dict вы можете удалить часть if isinstance(v, list) else v.

+0

Спасибо за ваш вклад! Это также отвечает на вторую часть моего вопроса о том, как загружать прямо таким образом. – Matteo

+0

@Matteo, вы очень желанны. – JAB

Смежные вопросы