将字典中的字符串键转换为整型键

68

我的问题与这个非常相似,只不过我有一个列表的字典,并且我想将键和每个列表中的所有元素从string更改为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", "12", "56", "130", "131"]}

遵循以下指示:

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

有没有办法在加载时直接完成它?


1
请注意,如果无法将“item”转换为整数,则“int(item)”会引发错误。由于您正在从文件中读取数据,因此重要的是将其包装在“try .. except”块中,以防出现意外值。 - vikki
@vikki - 感谢您的指出。虽然我还是个初学者,还没有接触到关于异常处理的教程部分,但我会记住的;D - Matteo
4个回答

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

无法适用于 d = {'1' : ['2','3']} ... 因为它的值是列表。 - Chris Arena
我的示例与我加载的JSON数据不一致。事实上,字典的每个元素都是一个列表,而不是单个整数。您建议我做出哪些更改? - Matteo
由于某些原因,coautorshipDictionary = {int(k):int(v) for k,v in json.load(json_data)} 对我来说不起作用。JSON已经被加载,但是值没有转换为INT。然而,d = {int(k):int(v) for k,v in d.items()} 却很好地工作了,所以我只是在第二步中加载了JSON,然后将其转换为INT。奇怪。 - Mark Cramer

7
类似Decency的答案,但利用object_hook参数:
与Decency的答案类似,但是利用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

这种方法的主要优点是,如果您最终得到任何嵌套字典,加载器将在加载数据时单独处理每个嵌套字典,而无需编写遍历结果字典的代码。如果您的JSON结构变得更加复杂,您还可以添加检查,以确保列表中的值不是数字字符串或列表本身也包含字典。如果您的数据仅具有顶层字典值的列表,则可以删除 if isinstance(v, list) else v 部分。

感谢您的贡献!这也回答了我关于如何以这种方式直接加载的第二个问题。 - Matteo
这里没有叫做“Decency”的人。它指的是哪个答案? - Peter Mortensen

3

如果你的值是可迭代的,就像你提供的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]}

对于第二部分问题,你可以在读取文件时使用一行的字典推导式。虽然这个方法很难懂。
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

这将产生与上面相同的输出。

非常感谢您的回答,它完美地解决了我的问题。您知道在加载数据时是否有直接实现这个功能的方法吗? - Matteo
当然可以,但不太美观。 - Chris Arena

0
dict = { 'a':'100', 'b':'200', 'c':'300', 'd':'four_hundred', 'e':'500' }
dict_parse = {k: int(v) if v.isnumeric() else v for k, v in dict.items()}
>>> dict_parse
{ 'a': 100, 'b': 200, 'c': 300, 'd':'four_hundred', 'e':500}

当有一个包含字母字符串和数字字符串值的 Python 对象(dict)时,我们可以使用 string.isnumeric() 映射并检查它们的类型。当处理 float 数字时,修改 if 语句以替换 小数点——你可以将相同的原则应用于 负数

dict = { 'a':'10.0', 'b':'20.12', 'c':'300.3', 'd':'four_hundred', 'e':'500' }
dict_parse = {k: float(v) if v.replace(".", "").isnumeric() else v for k, v in dict.items()}

>>> dict_parse
{ 'a': 10.0, 'b': 20.12, 'c': 300.3, 'd':'four_hundred', 'e':500}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接