Json, выбрасывающий dict, выдает TypeError: ключи должны быть строкой
Я пытаюсь преобразовать следующий dict
в JSON, используя json.dumps
:
{
'post_engaged': 36,
'post_impressions': 491,
'post_story': 23,
'comment_count': 6,
'created_time': '03:02 AM, Sep 30, 2012',
'message': 'Specialities of Shaktis and Pandavas. \n While having power, why there isn\\u2019t',
< built - in function id > : '471662059541196',
'status_type': 'status',
'likes_count': 22
} {
'post_engaged': 24,
'text': '30 Sept 2012 Avyakt Murlli ( Dual Voice )',
'post_story': 8,
'comment_count': 3,
'link': 'http:\\/\\/www.youtube.com\\/watch?v=VGmFj8g7JFA&feature=youtube_gdata_player',
'post_impressions': 307,
'created_time': '03:04 AM, Sep 30, 2012',
'message': 'Not available',
< built - in function id > : '529439300404155',
'status_type': 'video',
'likes_count': 7
} {
'post_engaged': 37,
'post_impressions': 447,
'post_story': 22,
'comment_count': 4,
'created_time': '03:11 AM, Sep 30, 2012',
'message': '30-09-12 \\u092a\\u094d\\u0930\\u093e\\u0924:\\u092e\\u0941\\u0930\\u0932\\u0940 \\u0913\\u0',
< built - in function id > : '471643246209744',
'status_type': 'status',
'likes_count': 20
} {
'post_engaged': 36,
'post_impressions': 423,
'post_story': 22,
'comment_count': 0,
'created_time': '03:04 AM, Sep 29, 2012',
'message': 'Essence: Sweet children, whenever you have time, earn the true income. Staying i',
< built - in function id > : '471274672913268',
'status_type': 'status',
'likes_count': 20
} {
'post_engaged': 16,
'text': 'Essence Of Murli 29-09-2012',
'post_story': 5,
'comment_count': 2,
'link': 'http:\\/\\/www.youtube.com\\/watch?v=i6OgmbRsJpg&feature=youtube_gdata_player',
'post_impressions': 291,
'created_time': '03:04 AM, Sep 29, 2012',
'message': 'Not available',
< built - in function id > : '213046588825668',
'status_type': 'video',
'likes_count': 5
}
Но это приводит меня к
TypeError : keys must be a string
Ошибка, скорее всего, связана с тем, что в нем содержится keys
, например:
<built-in function id>: '213046588825668'
Может ли кто-нибудь помочь мне с тем, как я должен удалить эти элементы из диктата?
Ответы
Ответ 1
Вы можете попробовать очистить его следующим образом:
for key in mydict.keys():
if type(key) is not str:
try:
mydict[str(key)] = mydict[key]
except:
try:
mydict[repr(key)] = mydict[key]
except:
pass
del mydict[key]
Это попытается преобразовать любой ключ, который не является строкой в строку. Любой ключ, который не может быть преобразован в строку или представлен в виде строки, будет удален.
Ответ 2
Изменив принятый ответ выше, я написал функцию для обработки словарей произвольной глубины:
def stringify_keys(d):
"""Convert a dict keys to strings if they are not."""
for key in d.keys():
# check inner dict
if isinstance(d[key], dict):
value = stringify_keys(d[key])
else:
value = d[key]
# convert nonstring to string if needed
if not isinstance(key, str):
try:
d[str(key)] = value
except Exception:
try:
d[repr(key)] = value
except Exception:
raise
# delete old key
del d[key]
return d
Ответ 3
Я знаю, что это старый вопрос, и на него уже есть принятый ответ, но, увы, принятый ответ просто неверен.
Настоящая проблема здесь заключается в том, что код, который генерирует dict, использует встроенную функцию id
в качестве ключа вместо литеральной строки "id"
. Таким образом, простое, очевидное и единственно правильное решение состоит в том, чтобы исправить эту ошибку в источнике: проверьте код, который генерирует dict, и замените id
на "id"
.
Ответ 4
В идеале вы хотели бы очистить свои данные, чтобы соответствовать типам данных, поддерживаемым JSON.
Если вы просто хотите исключить/или удалить эти элементы из dict во время сериализации, вы можете использовать skipkeys
аргумент, описание можно найти в разделе json.dump
json.dumps(obj, skipkeys=True)
Это решение намного чище и позволяет стандартной библиотеке обрабатывать ошибочные ключи для вас.
ВНИМАНИЕ: Вы должны полностью понимать последствия использования такого радикального метода, поскольку это приведет к потере данных для несовместимых типов данных, таких как ключи JSON.
Ответ 5
Может быть, это поможет:
your_dict = {("a", "b"):[1,2,3,4]}
# save
with open("file.json","w") as f:
f.write(json.dumps(list(your_dict.items())))
# load
with open("file.json","r") as f:
your_dict = dict([tuple((tuple(x[0]), x[1])) for x in json.loads(f.read())])
Ответ 6
Нолан Конавей ответ дает этот результат, например,
{"b'opening_hours'": {"b'1_from_hour'": 720, "b'1_to_hour'": 1440,
"b'1_break_from_hour'": 1440, "b'1_break_to_hour'": 1440,
"b'2_from_hour'": 720, "b'2_to_hour'": 1440, "b'2_break_from_hour'":
1440, "b'2_break_to_hour'": 1440, "b'3_from_hour'": 720,
"b'3_to_hour'": 1440, "b'3_break_from_hour'": 1440,
"b'3_break_to_hour'": 1440, "b'4_from_hour'": 720, "b'4_to_hour'":
1440, "b'4_break_from_hour'": 1440, "b'4_break_to_hour'": 1440,
"b'5_from_hour'": 720, "b'5_to_hour'": 1440, "b'5_break_from_hour'":
1440, "b'5_break_to_hour'": 1440, "b'6_from_hour'": 720,
"b'6_to_hour'": 1440, "b'6_break_from_hour'": 1440,
"b'6_break_to_hour'": 1440, "b'7_from_hour'": 720, "b'7_to_hour'":
1440, "b'7_break_from_hour'": 1440, "b'7_break_to_hour'": 1440}}
пока эта исправленная версия
import time
import re
import json
from phpserialize import *
class Helpers:
def stringify_keys(self,d):
"""Convert a dict keys to strings if they are not."""
for key in d.keys():
# check inner dict
if isinstance(d[key], dict):
value = Helpers().stringify_keys(d[key])
else:
value = d[key]
# convert nonstring to string if needed
if not isinstance(key, str):
try:
d[key.decode("utf-8")] = value
except Exception:
try:
d[repr(key)] = value
except Exception:
raise
# delete old key
del d[key]
return d
даст эту более чистую версию..
{"opening_hours": {"1_from_hour": 720, "1_to_hour": 1440,
"1_break_from_hour": 1440, "1_break_to_hour": 1440, "2_from_hour":
720, "2_to_hour": 1440, "2_break_from_hour": 1440, "2_break_to_hour":
1440, "3_from_hour": 720, "3_to_hour": 1440, "3_break_from_hour":
1440, "3_break_to_hour": 1440, "4_from_hour": 720, "4_to_hour": 1440,
"4_break_from_hour": 1440, "4_break_to_hour": 1440, "5_from_hour":
720, "5_to_hour": 1440, "5_break_from_hour": 1440, "5_break_to_hour":
1440, "6_from_hour": 720, "6_to_hour": 1440, "6_break_from_hour":
1440, "6_break_to_hour": 1440, "7_from_hour": 720, "7_to_hour": 1440,
"7_break_from_hour": 1440, "7_break_to_hour": 1440}}
Ответ 7
Возможно, это поможет следующему парню:
strjson = json.dumps(str(dic).replace("'",'"'))