将json列表简化为唯一的dict项

2024-04-27 12:37:38 发布

您现在位置:Python中文网/ 问答频道 /正文

python新手(也可以使用php)。。搜索了多个网站。。还有精神障碍。在

得到了一个json,并试图弄清楚如何获取一个包含dict的列表,并创建一个包含一组惟一dict的结果列表。。在

例如,以下是测试列表:

[{"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":""}]

尝试获取以下唯一dict的列表,以便不存在重复dict。在

^{pr2}$

我在考虑迭代初始列表,将每个dict复制到一个新列表中,并进行基本比较,如果下一个dict不在新列表中,则添加下一个dict。。还有别的/更好的方法吗?在

谢谢


Tags: 列表institutiondictclasspbssrstrmwrk2
3条回答

使用list(set(your_list_of_dicts))的最简单方法行不通,因为Python字典是可变的,不是散列的(也就是说,它们不实现__hash__)。这是因为Python不能保证字典的哈希在插入setdict之后不会改变。在

但是,在您的例子中,由于您(似乎根本没有)修改数据,您可以计算自己的哈希,并将其与字典一起使用,以相对容易地找到唯一的JSON对象,而不必对每个字典与其他字典进行完全的递归比较。在

首先,我们需要一个函数来计算字典的哈希值。与其尝试构建自己的哈希函数,不如使用^{}中的一个内置函数:

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 instance”的值,则这将失败或需要修改。此外,在您的示例中,您的字典是扁平的,但我将把它留给读者作为练习,如何扩展此解决方案以使用包含其他dict或列表的字典。)

由于dict_hash返回一个不可变的字符串,您现在可以使用字典来查找唯一的元素:

^{pr2}$

如果oldlist包含Python中的dict列表(例如,由于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的hash digest。在

如果我理解你的问题,你可以试试这个:

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)

输出:

^{pr2}$

编辑

注意,它会将您的dict列表转换为dict。也许对它进行进一步的操作会更容易。在

也可以将result转换为list:

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

注2

比较基于dict键,它将嵌套值提取到根级别。不知道操作是否可以访问。可能您不应该使用此解决方案。无论如何,它比使用repr()来比较dict快8倍。在

相关问题 更多 >