Python 将unicode字符串中的JSON解析为字典

Python 将unicode字符串中的JSON解析为字典,python,json,dictionary,unicode,Python,Json,Dictionary,Unicode,我有一个JSON输入,它由一个unicode字符字典列表组成: 例如: 如何将此字符串解析为字典列表?我尝试使用以下方法进行此操作: import json json_d = json.dumps(input) print type(json_d) # string object / Not list of dicts json_obj = json.loads(json_d) # unicode object / Not list of dicts 我无法解析JSON的内容: print

我有一个JSON输入,它由一个unicode字符字典列表组成: 例如:

如何将此字符串解析为字典列表?我尝试使用以下方法进行此操作:

import json
json_d = json.dumps(input)
print type(json_d)  # string object / Not list of dicts
json_obj = json.loads(json_d)  # unicode object / Not list of dicts
我无法解析JSON的内容:

print json_obj[0]["attributes"]
TypeError: string indices must be integers

我正在使用Python 2.7.11。谢谢你的帮助

试试一个简化的例子:

s = '[{attributes: { a: "foo", b: "bar" } }]'
主要问题是您的字符串不在有效的JSON中:

>>> json.loads(s)
[...]
JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
如果输入是由您生成的,请修复它。如果它来自其他地方,则需要在使用
json
模块加载它之前对其进行编辑

请注意,如果有一个正确的JSON,
.load()
方法是如何按预期工作的:

>>> s = '[{"attributes": { "a": "foo", "b": "bar" } }]'
>>> json.loads(s)
[{'attributes': {'a': 'foo', 'b': 'bar'}}]
>>> type(json.loads(s))
list

正如其他人提到的,您的输入数据不是JSON。理想情况下,应该将其固定在上游,以便获得有效的JSON

但是,如果这超出了您的控制范围,您可以将该数据转换为JSON

主要问题是所有那些没有引号的键。我们可以通过使用正则表达式在每行的第一个字段中搜索有效名称来解决这个问题。如果找到一个有效的名称,我们将其用双引号括起来

import json
import re

source = u'''[{
        attributes: {
            NAME: "Name_1ĂĂÎÎ",
            TYPE: "Tip1",
            LOC_JUD: "Bucharest",
            LAT_LON: "234343/432545",
            S70: "2342345",
            MAP: "Map_one",
            SCH: "1:5000",
            SURSA: "PPP"
        }
    }, {
        attributes: {
            NAME: "NAME_2șțț",
            TYPE: "Tip2",
            LOC_JUD: "cea",
            LAT_LON: "123/54645",
            S70: "4324",
            MAP: "Map_two",
            SCH: "1:578000",
            SURSA: "PPP"
        }
    }
]
'''

# Split source into lines, then split lines into colon-separated fields
a = [s.strip().split(': ') for s in source.splitlines()]

# Wrap names in first field in double quotes
valid_name = re.compile('(^\w+$)')
for row in a:
    row[0] = valid_name.sub(r'"\1"', row[0])

# Recombine the data and load it
data = json.loads(' '.join([': '.join(row) for row in a]))

# Test 

print data[0]["attributes"]
print '- ' * 30
print json.dumps(data, indent=4, ensure_ascii=False)
输出

{u'LOC_JUD': u'Bucharest', u'NAME': u'Name_1\u0102\u0102\xce\xce', u'MAP': u'Map_one', u'SURSA': u'PPP', u'S70': u'2342345', u'TYPE': u'Tip1', u'LAT_LON': u'234343/432545', u'SCH': u'1:5000'}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[
    {
        "attributes": {
            "LOC_JUD": "Bucharest", 
            "NAME": "Name_1ĂĂÎÎ", 
            "MAP": "Map_one", 
            "SURSA": "PPP", 
            "S70": "2342345", 
            "TYPE": "Tip1", 
            "LAT_LON": "234343/432545", 
            "SCH": "1:5000"
        }
    }, 
    {
        "attributes": {
            "LOC_JUD": "cea", 
            "NAME": "NAME_2șțț", 
            "MAP": "Map_two", 
            "SURSA": "PPP", 
            "S70": "4324", 
            "TYPE": "Tip2", 
            "LAT_LON": "123/54645", 
            "SCH": "1:578000"
        }
    }
]
请注意,此代码有点脆弱。它可以处理问题中所示格式的数据,但如果一行上有多个键值对,它就不起作用


正如我前面所说的,解决这个问题的最佳方法是上游,在那里生成非JSON。

只需执行
JSON.loads(input)
。转储是相反的过程,您不需要它,但他需要正确的字符串化json。当前输入没有在引号中包装属性。我想这将是一个问题。您需要使用
json.loads
而不是
json.dumps
<代码>加载用于反序列化<代码>转储用于序列化。您正在将unicode字符串序列化为JSON字符串。同意@Nishant Srivastava。请使用JSON验证程序检查输入@NishantSrivastava,这意味着我接收的unicode字符串不是JSON?我从其他地方接收输入。如果我将JSON编辑为:''s='[{“attributes”:{“a”:“foo”,“b”:“bar”}]''',然后运行“JSON.loads(s)”,我会得到一个字符串,而不是一个字典列表…@Litwos:请参阅我更新的答案,如果JSON是正确的,该方法会工作(您可以自己复制)。;-)就是这样,谢谢。我现在将尝试修改建议的输入。事实上,格式并不总是这样,所以我需要解决上游的问题。
{u'LOC_JUD': u'Bucharest', u'NAME': u'Name_1\u0102\u0102\xce\xce', u'MAP': u'Map_one', u'SURSA': u'PPP', u'S70': u'2342345', u'TYPE': u'Tip1', u'LAT_LON': u'234343/432545', u'SCH': u'1:5000'}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[
    {
        "attributes": {
            "LOC_JUD": "Bucharest", 
            "NAME": "Name_1ĂĂÎÎ", 
            "MAP": "Map_one", 
            "SURSA": "PPP", 
            "S70": "2342345", 
            "TYPE": "Tip1", 
            "LAT_LON": "234343/432545", 
            "SCH": "1:5000"
        }
    }, 
    {
        "attributes": {
            "LOC_JUD": "cea", 
            "NAME": "NAME_2șțț", 
            "MAP": "Map_two", 
            "SURSA": "PPP", 
            "S70": "4324", 
            "TYPE": "Tip2", 
            "LAT_LON": "123/54645", 
            "SCH": "1:578000"
        }
    }
]