2017-04-05 88 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