简体   繁体   中英

Error in writing Python dictionary to a file

This is a simplified version of my code:

test={}
for i in range(10):
   for j in range(15):
     test[i,j]=i*j
with open('boo.json', 'w') as f:
    json.dump(test, f)

and I got the following error:

raise TypeError("key " + repr(key) + " is not a string")

Any solution?

The JSON format requires object keys to be strings; you cannot use tuples of numbers as keys.

You'll have to find a representation that uses strings instead that models your data well enough for you. You could use nested dictionaries and convert your numbers to strings, for example:

test = {}
for i in range(10):
    nested = test[str(i)] = {}
    for j in range(15):
        nested[str(j)] = i * j

with open('boo.json', 'w') as f:
    json.dump(test, f)

If you must have one level only, you'll have to produce a string with both integers in it; you could create a comma-separated key:

test['{},{}'.format(i, j)] = i * j

or use any other separator; you'll have to teach the JSON consumers to expect to parse those keys, of course.

Note that for your demo datastructure it'd be much easier to just use lists (JSON arrays); these are addressable with numbers after all:

test = []
for i in range(10):
    nested = []
    for j in range(15):
        nested.append(i * j)

or using a list comprehension:

test = [[i * j for j in range(15)] for i in range(10)]

Demo:

>>> import json
>>> test = {}
>>> for i in range(10):
...     nested = test[str(i)] = {}
...     for j in range(15):
...         nested[str(j)] = i * j
... 
>>> print json.dumps(test, sort_keys=True, indent=4, separators=(',', ': '))
{
    "0": {
        "0": 0,
        "1": 0,
        "10": 0,
        "11": 0,
        "12": 0,
        "13": 0,
        "14": 0,
        "2": 0,
        "3": 0,
        "4": 0,
        "5": 0,
        "6": 0,
        "7": 0,
        "8": 0,
        "9": 0
    },
    "1": {
        "0": 0,
        "1": 1,
        "10": 10,
        "11": 11,
        "12": 12,
        "13": 13,
        "14": 14,
        "2": 2,
        "3": 3,
        "4": 4,
        "5": 5,
        "6": 6,
        "7": 7,
        "8": 8,
        "9": 9
    },
    "2": {
        "0": 0,
        "1": 2,
        "10": 20,
        "11": 22,
        "12": 24,
        "13": 26,
        "14": 28,
        "2": 4,
        "3": 6,
        "4": 8,
        "5": 10,
        "6": 12,
        "7": 14,
        "8": 16,
        "9": 18
    },
    "3": {
        "0": 0,
        "1": 3,
        "10": 30,
        "11": 33,
        "12": 36,
        "13": 39,
        "14": 42,
        "2": 6,
        "3": 9,
        "4": 12,
        "5": 15,
        "6": 18,
        "7": 21,
        "8": 24,
        "9": 27
    },
    "4": {
        "0": 0,
        "1": 4,
        "10": 40,
        "11": 44,
        "12": 48,
        "13": 52,
        "14": 56,
        "2": 8,
        "3": 12,
        "4": 16,
        "5": 20,
        "6": 24,
        "7": 28,
        "8": 32,
        "9": 36
    },
    "5": {
        "0": 0,
        "1": 5,
        "10": 50,
        "11": 55,
        "12": 60,
        "13": 65,
        "14": 70,
        "2": 10,
        "3": 15,
        "4": 20,
        "5": 25,
        "6": 30,
        "7": 35,
        "8": 40,
        "9": 45
    },
    "6": {
        "0": 0,
        "1": 6,
        "10": 60,
        "11": 66,
        "12": 72,
        "13": 78,
        "14": 84,
        "2": 12,
        "3": 18,
        "4": 24,
        "5": 30,
        "6": 36,
        "7": 42,
        "8": 48,
        "9": 54
    },
    "7": {
        "0": 0,
        "1": 7,
        "10": 70,
        "11": 77,
        "12": 84,
        "13": 91,
        "14": 98,
        "2": 14,
        "3": 21,
        "4": 28,
        "5": 35,
        "6": 42,
        "7": 49,
        "8": 56,
        "9": 63
    },
    "8": {
        "0": 0,
        "1": 8,
        "10": 80,
        "11": 88,
        "12": 96,
        "13": 104,
        "14": 112,
        "2": 16,
        "3": 24,
        "4": 32,
        "5": 40,
        "6": 48,
        "7": 56,
        "8": 64,
        "9": 72
    },
    "9": {
        "0": 0,
        "1": 9,
        "10": 90,
        "11": 99,
        "12": 108,
        "13": 117,
        "14": 126,
        "2": 18,
        "3": 27,
        "4": 36,
        "5": 45,
        "6": 54,
        "7": 63,
        "8": 72,
        "9": 81
    }
}

or producing a flat structure:

>>> test = {}
>>> for i in range(10):
...     for j in range(15):
...         test['{},{}'.format(i, j)] = i * j
... 
>>> print json.dumps(test, sort_keys=True, indent=4, separators=(',', ': '))
{
    "0,0": 0,
    "0,1": 0,
    "0,10": 0,
    "0,11": 0,
    "0,12": 0,
    "0,13": 0,
    "0,14": 0,
    "0,2": 0,
    "0,3": 0,
    "0,4": 0,
    "0,5": 0,
    "0,6": 0,
    "0,7": 0,
    "0,8": 0,
    "0,9": 0,
    "1,0": 0,
    "1,1": 1,
    "1,10": 10,
    "1,11": 11,
    "1,12": 12,
    "1,13": 13,
    "1,14": 14,
    "1,2": 2,
    "1,3": 3,
    "1,4": 4,
    "1,5": 5,
    "1,6": 6,
    "1,7": 7,
    "1,8": 8,
    "1,9": 9,
    "2,0": 0,
    "2,1": 2,
    "2,10": 20,
    "2,11": 22,
    "2,12": 24,
    "2,13": 26,
    "2,14": 28,
    "2,2": 4,
    "2,3": 6,
    "2,4": 8,
    "2,5": 10,
    "2,6": 12,
    "2,7": 14,
    "2,8": 16,
    "2,9": 18,
    "3,0": 0,
    "3,1": 3,
    "3,10": 30,
    "3,11": 33,
    "3,12": 36,
    "3,13": 39,
    "3,14": 42,
    "3,2": 6,
    "3,3": 9,
    "3,4": 12,
    "3,5": 15,
    "3,6": 18,
    "3,7": 21,
    "3,8": 24,
    "3,9": 27,
    "4,0": 0,
    "4,1": 4,
    "4,10": 40,
    "4,11": 44,
    "4,12": 48,
    "4,13": 52,
    "4,14": 56,
    "4,2": 8,
    "4,3": 12,
    "4,4": 16,
    "4,5": 20,
    "4,6": 24,
    "4,7": 28,
    "4,8": 32,
    "4,9": 36,
    "5,0": 0,
    "5,1": 5,
    "5,10": 50,
    "5,11": 55,
    "5,12": 60,
    "5,13": 65,
    "5,14": 70,
    "5,2": 10,
    "5,3": 15,
    "5,4": 20,
    "5,5": 25,
    "5,6": 30,
    "5,7": 35,
    "5,8": 40,
    "5,9": 45,
    "6,0": 0,
    "6,1": 6,
    "6,10": 60,
    "6,11": 66,
    "6,12": 72,
    "6,13": 78,
    "6,14": 84,
    "6,2": 12,
    "6,3": 18,
    "6,4": 24,
    "6,5": 30,
    "6,6": 36,
    "6,7": 42,
    "6,8": 48,
    "6,9": 54,
    "7,0": 0,
    "7,1": 7,
    "7,10": 70,
    "7,11": 77,
    "7,12": 84,
    "7,13": 91,
    "7,14": 98,
    "7,2": 14,
    "7,3": 21,
    "7,4": 28,
    "7,5": 35,
    "7,6": 42,
    "7,7": 49,
    "7,8": 56,
    "7,9": 63,
    "8,0": 0,
    "8,1": 8,
    "8,10": 80,
    "8,11": 88,
    "8,12": 96,
    "8,13": 104,
    "8,14": 112,
    "8,2": 16,
    "8,3": 24,
    "8,4": 32,
    "8,5": 40,
    "8,6": 48,
    "8,7": 56,
    "8,8": 64,
    "8,9": 72,
    "9,0": 0,
    "9,1": 9,
    "9,10": 90,
    "9,11": 99,
    "9,12": 108,
    "9,13": 117,
    "9,14": 126,
    "9,2": 18,
    "9,3": 27,
    "9,4": 36,
    "9,5": 45,
    "9,6": 54,
    "9,7": 63,
    "9,8": 72,
    "9,9": 81
}

You need your json object keys to be strings.

Try doing this instead:

#!/usr/bin/env python3
import json

test={}
for i in range(10):
   for j in range(15):
     test["%s,%s" %(i,j)]=i*j
with open('boo.json', 'w') as f:
    json.dump(test, f)

This will put the values for i and j into string format ( with a comma in between) so your key will be a string.

@Martijn does a better job explaining in his answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM