怎么用python从json中的嵌套列表字典中提取数据?

jasonusaco
  • 5
新手上路,请多包涵

问题描述

我有个json文件,里面存了一个大列表,列表里嵌套了很多字典,每个字典里面的value又是用列表存起来的,像这样:
[{"domain": ["http://www.akzonel.com", "http://www.AK20Nobel.com"]},{"domain": ["http://www.tcl.com", "http://nyell.td.com"]},......]
想知道如何把所有的value全部提取出来,单独存在一个列表中

问题出现的环境背景及自己尝试过哪些方法

这是我尝试的代码,提取前五个字典的:

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)
import json
def resolveJson():

file = '../save.json'
f_obj = open(file)
number = json.load(f_obj)
res = []
for i in range(0,5):
    domain = number[i]["domain"]
    res.append(domain)
print(res)

resolveJson()

你期待的结果是什么?实际看到的错误信息又是什么?

目前得到是这样:
[['http://www.akzonel.com', 'http://www.AK20Nobel.com'], ['http://www.tcl.com', 'http://nyell.td.com', 'http://www.tclcomm.com', 'http://www.tcl.com', 'http://www.tcldisplay.com', 'http://www.tcl-cctv.com']......],说白了还是列表里面嵌套列表,而没有把所有的网址都取出来存到一个大列表中。
希望得到结果:
['http://www.akzonel.com', 'http://www.AK20Nobel.com','http://www.tcl.com', 'http://nyell.td.com', 'http://www.tclcomm.com', 'http://www.tcl.com', 'http://www.tcldisplay.com', 'http://www.tcl-cctv.com',.......]
有人能帮忙吗?

回复
阅读 11.1k
4 个回答

不知道你的数据量有多大,有很多种方法解决这个问题,其中比较简单的一种就是递归。注意,如果递归方法出现溢出,可以考虑改写成循环。

既然你已经得到了嵌套了列表,那么我就从你的嵌套列表开始操作。假设你的数据是这样的:

data = [
    ['http://www.akzonel.com', 'http://www.AK20Nobel.com'],
    ['http://www.tcl.com', 'http://nyell.td.com', 'http://www.tclcomm.com',
        'http://www.tcl.com', 'http://www.tcldisplay.com', 'http://www.tcl-cctv.com']
]

那么我们可以定义一个函数read和一个全局变量results,递归调用来获取所有结果:

results = []
def read(my_list):
    for item in my_list:
        if isinstance(item, str):
            results.append(item)
        else:
            read(item)

直接输入data

read(data)
print(results)

最终的结果为:

['http://www.akzonel.com', 'http://www.AK20Nobel.com', 'http://www.tcl.com', 'http://nyell.td.com', 'http://www.tclcomm.com', 'http://www.tcl.com', 'http://www.tcldisplay.com', 'http://www.tcl-cctv.com']

完整代码如下:

data = [
    ['http://www.akzonel.com', 'http://www.AK20Nobel.com'],
    ['http://www.tcl.com', 'http://nyell.td.com', 'http://www.tclcomm.com',
        'http://www.tcl.com', 'http://www.tcldisplay.com', 'http://www.tcl-cctv.com']
]

results = []
def read(my_list):
    for item in my_list:
        if isinstance(item, str):
            results.append(item)
        else:
            read(item)


read(data)
print(results)

法一:判断类型,拆分

In [17]: old_list = [['http://www.akzonel.com', 'http://www.AK20Nobel.com'], ['http://www.tcl.com', 'http://nyell.td.com', 'http
    ...: ://www.tclcomm.com', 'http://www.tcl.com', 'http://www.tcldisplay.com', 'http://www.tcl-cctv.com']]

In [23]: def flatten(lst):
    ...:     return sum( ([x] if not isinstance(x, list) else flatten(x) for x in lst), [])

In [24]: flatten(old_list)
Out[24]:
['http://www.akzonel.com',
 'http://www.AK20Nobel.com',
 'http://www.tcl.com',
 'http://nyell.td.com',
 'http://www.tclcomm.com',
 'http://www.tcl.com',
 'http://www.tcldisplay.com',
 'http://www.tcl-cctv.com']

法二:numpy flatten属性

import numpy as np 
new_list = np.array(old_list).flatten()
# coding: utf-8
from __future__ import unicode_literals

lst = [{"domain": ["http://www.akzonel.com", "http://www.AK20Nobel.com"]},{"domain": ["http://www.tcl.com", "http://nyell.td.com"]}]

#列表推导式, 推荐
lst1 = [_['domain'] for _ in lst]
print [_ for item in lst for _ in item['domain']]


#使用chain
from itertools import chain
lst1 = [_['domain'] for _ in lst]
print list(chain(*lst1))

#使用reduce
import operator
lst1 = [_['domain'] for _ in lst]
print reduce(operator.add, lst1)

不知道是不是需要这样效果

# 得到的 json
json = [{"domain": ["http://www.akzonel.com", "http://www.AK20Nobel.com"]},{"domain": ["http://www.tcl.com", "http://nyell.td.com"]}]
# 存储的列表
data = [] 

for i in json:
    data.extend(i["domain"])
    
print(data)
# ['http://www.akzonel.com', 'http://www.AK20Nobel.com', 'http://www.tcl.com', 'http://nyell.td.com']
宣传栏