2012-01-10 56 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