2016-09-30 53 views
2

我有一个看起来像这样JSON文件如何所有列表转换为集:当JSON文件加载

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

我可以在这个数据很容易读:

import json 

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

然后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']}} 

但是,对于我的进一步分析,最好是使用sets而不是lists。当然,我可以转换listssets我已经在数据读取之后:

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

这给了我想要的输出:

print data['K2'] 

产量

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

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

回答

5

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

你必须递归更新解码后的结果,而不是事后:

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 

此处理列表的方式在任何嵌套字典深度:

>>> 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'])}} 

考虑到然而,含有其他字典名单不能被处理,因为字典不可排除。

如果你希望找到嵌套其他列表中列出,你必须切换到使用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 
+0

工作正常,upvoted。不会有任何嵌套列表,但感谢提到'frozenset'部分;以前没有听说过这个。 – Cleb

2

下面是一个内衬表达实现这种使用dict comprehension:你想让它使用loop实现

>>> {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'}}} 

然而,在情况下,下面是例子:

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'}}} 
+0

正常工作为好,upvoted。 – Cleb