如何在加载json文件时将所有列表转换为集合

[英]How to convert all lists to sets when json file is loaded


I have json files that look like this:

我有json文件,如下所示:

{
    "K1": {
        "p": [
            "A"
        ], 
        "s": [
            "B", 
            "C"
        ]
    }, 
    "K2": {
        "p": [
            "A", 
            "F"
        ], 
        "s": [
            "G", 
            "H",
            "J"
        ]
    }
}

I can easily read in this data:

我可以轻松阅读这些数据:

import json

with open('json_lists_to_sets.json') as fi:
    data = json.load(fi)

Then data looks as follows:

然后数据如下:

{u'K2': {u'p': [u'A', u'F'], u's': [u'G', u'H', u'J']}, u'K1': {u'p': [u'A'], u's': [u'B', u'C']}}

For my further analysis, however, it would be better to use sets instead of lists. I can of course convert lists to sets after I have read in the data:

但是,对于我的进一步分析,最好使用集合而不是列表。在读完数据后,我当然可以将列表转换为集合:

for vi in data.values():
    vi['p'] = set(vi['p'])
    vi['s'] = set(vi['s'])

which gives me the desired output:

这给了我想要的输出:

print data['K2']

yields

产量

{u'p': {u'A', u'F'}, u's': {u'G', u'H', u'J'}}

My questions is whether I can convert these lists to sets directly when I read in the data in the json.load command, so something like "convert all lists you find to sets". Does something like this exist?

我的问题是,当我读入json.load命令中的数据时,是否可以直接将这些列表转换为集合,所以类似“将所有列表转换为集合”。这样的事情存在吗?

2 个解决方案

#1


5  

Although the json library offers many hooks to alter decoding, there is no hook to hook into loading a JSON array.

虽然json库提供了许多钩子来改变解码,但是没有挂钩来加载JSON数组。

You'll have to recursively update the decoded result afterwards instead:

您将不得不以后递归更新解码结果:

def to_sets(o):
    if isinstance(o, list):
        return {to_sets(v) for v in o}
    elif isinstance(o, dict):
        return {k: to_sets(v) for k, v in o.items()}
    return o

This handles lists at any nested dictionary depth:

这将处理任何嵌套字典深度的列表:

>>> to_sets(data)
{u'K2': {u'p': set([u'A', u'F']), u's': set([u'H', u'J', u'G'])}, u'K1': {u'p': set([u'A']), u's': set([u'C', u'B'])}}

Take into account however, that lists containing other dictionaries can't be handled because dictionaries are not hashable.

但是,请注意,由于字典不可清除,因此无法处理包含其他字典的列表。

If you expect to find lists nested inside other lists, you'd have to switch to using a frozenset() rather than a set() to be able to nest those:

如果您希望找到嵌套在其他列表中的列表,则必须切换到使用frozenset()而不是set()才能嵌套:

def to_sets(o):
    if isinstance(o, list):
        return frozenset(to_sets(v) for v in o)
    elif isinstance(o, dict):
        return {k: to_sets(v) for k, v in o.items()}
    return o

#2


2  

Below is the one liner expression to achieve this using dict comprehension:

下面是使用dict理解实现此目的的一个线性表达式:

>>> {key: {k: set(v) for k, v in nested_dict.items()} for key, nested_dict in data.items()}
{'K2': {'s': {'H', 'G', 'J'}, 'p': {'A', 'F'}}, 'K1': {'s': {'B', 'C'}, 'p': {'A'}}}

However, in case you want achieve it using loop, below is the example:

但是,如果您想使用循环实现它,下面是示例:

data = {u'K2': {u'p': [u'A', u'F'], u's': [u'G', u'H', u'J']}, u'K1': {u'p': [u'A'], u's': [u'B', u'C']}}
for key, nested_dict in data.items():
    data[key] = {k: set(v) for k, v in nested_dict.items()}

# Value of 'data': {'K2': {'s': {'H', 'G', 'J'}, 'p': {'A', 'F'}}, 'K1': {'s': {'B', 'C'}, 'p': {'A'}}}

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2016/09/30/72f6d80b11dc894101ad7c650a447e5.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com