如何在加載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