Json转储dict抛出TypeError:keys必须是一个字符串

时间:2012-10-04 19:30:49

标签: python json simplejson

我正在尝试转换以下dict into JSON using 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

我猜错误可能会弹出,因为dict包含一些元素,如:

 <built-in function id>: '213046588825668'

有人可以指导我,我应该如何从字典中删除这些元素?

7 个答案:

答案 0 :(得分:16)

您可以尝试像这样清理它:

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]

这将尝试将任何非字符串的键转换为字符串。任何无法转换为字符串或表示为字符串的键都将被删除。

答案 1 :(得分:8)

修改上面接受的答案,我编写了一个函数来处理任意深度的字典:

def stringify_keys(d):
    """Convert a dict's 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

答案 2 :(得分:3)

我知道这是一个古老的问题,它已经有一个可以接受的答案,但是可惜,这个可以接受的答案完全是错误的。

这里的真正问题是生成字典的代码使用内置id函数作为键而不是文字字符串"id"作为键。因此,简单,明显且唯一正确的解决方案是从源头修复此错误:检查生成dict的代码,并将id替换为"id"

答案 3 :(得分:0)

例如,诺兰·科纳韦(Nolan conaway)的答案给出了这个结果

  

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

此修订版

导入时间 汇入 导入json 从phpserialize导入*

class Helpers:
   def stringify_keys(self,d):
    """Convert a dict's 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个小时”:1440,“ 5个小时起”:1440,“ 5个小时起”:   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}}

答案 4 :(得分:0)

也许这会有所帮助:

Makefile:439: recipe for target 'mysql.o' failed
make[2]: *** [mysql.o] Error 1
make[2]: Leaving directory '/home/user/Downloads/mysql-3.23.54a/client'
Makefile:281: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/user/Downloads/mysql-3.23.54a'
Makefile:223: recipe for target 'all' failed
make: *** [all] Error 2

答案 5 :(得分:-1)

理想情况下,您希望清除数据,以便遵守JSON支持的数据类型。

如果您只是想在序列化时从dict中取消/删除这些元素,则可以使用skipkeys argument,说明可以在json.dump section

中找到
  

如果skipkeys为true(默认值:False),则表示非   基本类型(str,int,float,bool,None)将被跳过,而不是   引发TypeError。

json.dumps(obj, skipkeys=True)

此解决方案更加简洁,允许标准库为您处理错误的密钥。

警告:您必须完全理解使用这种过分的方法的含义,因为这将导致不兼容的数据类型(如JSON密钥)的数据丢失。

答案 6 :(得分:-7)

也许这会对下一个人有所帮助:

strjson = json.dumps(str(dic).replace("'",'"'))