2017-04-05 29 views
-1

我有一个JSON输入一个包含字典为Unicode字符的列表: 例子:解析JSON从unicode字符串作为字典

input = 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" 
     } 
    } 
] 
' 

如何可以解析这个字符串变成词典列表?我试图做到这一点使用:

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。谢谢你的帮助!

+0

只要做'json.loads(输入)'。转储是相反的过程,你不需要它。 – RemcoGerlich

+4

但他会需要正确串化的json。当前输入没有包含在引号内的属性。我想这会是一个问题。 –

+0

您需要使用'json.loads'而不是'json.dumps'。 'load'用于*反序列化*。 'dump'用于*序列化*。您正在将一个unicode字符串*序列化为一个JSON字符串*。 –

回答

1

尝试一个简单的例子:

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怎么样,​​方法按预期工作:

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

我从其他地方接收输入。如果我编辑我的JSON为:'''s ='[{“attributes”:{“a”:“foo”,“b”:“bar”}}]'''',然后运行'json.loads (s)',我得到一个字符串,而不是一个字典列表... – Litwos

+0

@Litwos:看到我更新的答案,如果JSON是正确的,该方法的作品(你可以自己重现)。 ;-) – Peque

+0

它的工作原理就是这样,谢谢。我现在将尝试修改输入 – Litwos

1

正如其他人所说,你的输入数据不是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正在生成。

+0

感谢您的建议。事实上,格式并不总是这样,所以我需要在上游解决问题。 – Litwos