2012-01-10 55 views
0

python的新手(可以使用php以及)..搜索各種網站/ SO ..並仍然有一個心理障礙。將json列表簡化爲獨特的字典項目

得到了JSON,並試圖找出如何拍攝包含類型的字典列表,並創建一個具有一套獨特的類型的字典結果列表..

作爲
的一個實例,下面是測試列表:

[{"pStart1a": {"termVal":"1122","termMenu":"CLASS_SRCH_WRK2_STRM","instVal":"OSUSI", 
"instMenu":"CLASS_SRCH_WRK2_INSTITUTION","goBtn":"CLASS_SRCH_WRK2_SSR_PB_SRCH", 
"pagechk":"CLASS_SRCH_WRK2_SSR_PB_SRCH","nPage":"CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH"}, 
"pSearch1a": 
{"chk":"CLASS_SRCH_WRK2_MON","srchbtn":"DERIVED_CLSRCH_SSR_EXPAND_COLLAPS"}}, 
{"pStart1":""}, 
{"pStart1a":{"termVal":"1122","termMenu":"CLASS_SRCH_WRK2_STRM","instVal":"OSUSI", 
"instMenu":"CLASS_SRCH_WRK2_INSTITUTION","goBtn":"CLASS_SRCH_WRK2_SSR_PB_SRCH", 
"pagechk":"CLASS_SRCH_WRK2_SSR_PB_SRCH","nPage":"CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH"}, 
"pSearch1a": 
{"chk":"CLASS_SRCH_WRK2_MON","srchbtn":"DERIVED_CLSRCH_SSR_EXPAND_COLLAPS"}}, 
{"pStart1":""}] 

試圖獲得以下,唯一的字典列表,所以沒有重複的字典。

[ 
    {"pStart1a": 
    {"termVal":"1122","termMenu":"CLASS_SRCH_WRK2_STRM","instVal":"OSUSI", 
    "instMenu":"CLASS_SRCH_WRK2_INSTITUTION","goBtn":"CLASS_SRCH_WRK2_SSR_PB_SRCH", 
    pagechk":"CLASS_SRCH_WRK2_SSR_PB_SRCH","nPage":"CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH"}, 
    "pSearch1a": 
    {"chk":"CLASS_SRCH_WRK2_MON","srchbtn":"DERIVED_CLSRCH_SSR_EXPAND_COLLAPS"}}, 
    {"pStart1":""}] 

我正在考慮通過初始列表進行迭代,每一個複製詞典到一個新的列表,並做了基本的比較,將在未來字典,如果它不在新的清單..有另一個/更好的辦法?

感謝

+2

是否有原因,你不使用Python的內置json庫? – Peter 2012-01-10 18:17:15

+0

它是否存在實際問題?你會如何處理結果列表?也許你可以使用不同的格式或簡化數據? – reclosedev 2012-01-10 19:23:51

回答

-1

如果我理解你的問題的權利,你可以試試這個:

import json 
from pprint import pprint 

json_string = """[{"pStart1a": {"termVal":"1122","termMenu":"CLASS_SRCH_WRK2_STRM","instVal":"OSUSI", 
"instMenu":"CLASS_SRCH_WRK2_INSTITUTION","goBtn":"CLASS_SRCH_WRK2_SSR_PB_SRCH", 
"pagechk":"CLASS_SRCH_WRK2_SSR_PB_SRCH","nPage":"CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH"}, 
"pSearch1a": 
{"chk":"CLASS_SRCH_WRK2_MON","srchbtn":"DERIVED_CLSRCH_SSR_EXPAND_COLLAPS"}}, 
{"pStart1":""}, 
{"pStart1a":{"termVal":"1122","termMenu":"CLASS_SRCH_WRK2_STRM","instVal":"OSUSI", 
"instMenu":"CLASS_SRCH_WRK2_INSTITUTION","goBtn":"CLASS_SRCH_WRK2_SSR_PB_SRCH", 
"pagechk":"CLASS_SRCH_WRK2_SSR_PB_SRCH","nPage":"CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH"}, 
"pSearch1a": 
{"chk":"CLASS_SRCH_WRK2_MON","srchbtn":"DERIVED_CLSRCH_SSR_EXPAND_COLLAPS"}}, 
{"pStart1":""}] 
""" 

result = {} 
for dct in json.loads(json_string): 
    for key, value in dct.iteritems(): 
     result[key] = value 

pprint(result) 

輸出:

{u'pSearch1a': {u'chk': u'CLASS_SRCH_WRK2_MON', 
       u'srchbtn': u'DERIVED_CLSRCH_SSR_EXPAND_COLLAPS'}, 
u'pStart1': '', 
u'pStart1a': {u'goBtn': u'CLASS_SRCH_WRK2_SSR_PB_SRCH', 
       u'instMenu': u'CLASS_SRCH_WRK2_INSTITUTION', 
       u'instVal': u'OSUSI', 
       u'nPage': u'CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH', 
       u'pagechk': u'CLASS_SRCH_WRK2_SSR_PB_SRCH', 
       u'termMenu': u'CLASS_SRCH_WRK2_STRM', 
       u'termVal': u'1122'}} 

編輯

注意,將其轉換列表字典,字典。也許它會更容易做進一步的操作。

也有可能,轉換result列出:

list_result = [{key:value} for key, value in result.iteritems()] 

注2:

比較是基於字典的鍵,和它提取嵌套值根級別。不知道OP是否可訪問。可能你不應該使用此解決方案。無論如何,它比使用repr()比較字典的速度快8倍(在這個數據上)。

+0

這個答案顯然是錯誤的。結果應該是由OP指定的唯一字典列表。 – 2012-01-10 18:34:19

+0

@RomanSusi,無論如何,我認爲這個解決方案擁有生命權,因爲字典上的操作比字典上的操作更簡單。 – reclosedev 2012-01-10 18:38:48

+0

操作可能會更容易,但我想你的解決方案不適用於OP的問題。 – 2012-01-10 18:45:52

2

如果oldlist包含在Python類型的字典列表(例如,作爲json.loads的結果(jsonstring)),那麼新的列表,可以通過一些構造是這樣的:

encountered = set() 
newlist = [] 
for i in oldlist: 
    repr_i = repr(i) 
    if repr_i in encountered: 
     continue 
    encountered.add(repr_i) 
    newlist.append(i) 

print newlist 

其他一些功能可以用來代替repr,例如repr的哈希摘要。

+0

您可以通過將'repr(i)'的結果存儲在一個變量中來提高效率。 – dcrosta 2012-01-10 18:37:43

+0

謝謝。更新。 – 2012-01-10 18:42:02

+0

就目前而言,這並不能保證工作:如果兩個項目具有相同的散列值,則可以生成不同的'repr',具體取決於在dict中輸入項目的順序。 – ekhumoro 2012-01-10 19:03:05

0

最簡單的方法 - 使用list(set(your_list_of_dicts))將不起作用,因爲Python字典是可變的且不可哈希的(也就是說,它們不實現__hash__)。這是因爲Python不能保證字典的散列在將其插入setdict後不會更改。

但是,就你而言,由於你(似乎不是)修改數據,你可以計算自己的散列,並將其與字典一起使用,以便相對容易地找到唯一的JSON對象,而無需將每個字典與其他字典進行完整的遞歸比較。

首先,我們需要一個函數來計算字典的散列。而不是試圖建立自己的散列函數,讓我們使用內置者之一從hashlib

def dict_hash(d): 
    out = hashlib.md5() 
    for key, value in d.iteritems(): 
     out.update(unicode(key)) 
     out.update(unicode(value)) 
    return out.hexdigest() 

(請注意,這依賴於unicode(...)爲每個值返回一些獨特的 - 如果有自定義在字典中的類__unicode__返回類似「MyClass實例」的字典,這將失敗或將需要修改。另外,在你的例子中,你的字典是平的,但我將它作爲練習給讀者如何擴展這個解決方案與包含其他字典或列表的字典一起工作。)

由於dict_hash返回一個字符串,它是不變的能夠,你現在可以使用字典來找到獨特的元素:

uniques_map = {} 
for d in list_of_dicts: 
    uniques[dict_hash(d)] = d 
unique_dicts = uniques_map.values() 
+0

嗨dcrosta ...試圖實施/測試/學習你發佈..什麼是「唯一」的定義是一個列表/字典?我會認爲它不是一個列表,因爲「dict_hash」的輸出是一個str ...謝謝 – 2012-01-10 19:13:44

+0

'uniques'是一個字典,是的 - 但是在字典中調用'.values()'會給你一個列表值(不是鍵)來自字典。由於我們將原始字典'd'存儲爲每個鍵(其中鍵是散列)的值,因此'.values()'給出了具有唯一散列的字典的列表(即,來自原始的唯一字典'list_of_dicts') – dcrosta 2012-01-10 20:11:17

相關問題