無限遍歷,python實現在多維嵌套字典、列表、元組的JSON中獲取數據

原文鏈接:

http://www.cnblogs.com/Detector/p/8085460.html


背景

  接口自動化過程中,接口返回的爲  列表字典循環嵌套  的數據,怎樣通過一個key值,直接獲取到被包裹多層的數據成爲了擺在我面前的一個問題,

  爲此,我在某度上面進行了搜索,發現很多人遇到類似的問題,但是解決方案都不夠完善,不能達到我想要的結果,所以自己嘗試寫了一個

思路

  開始時的想法是,對數據類型進行判斷,然後做對應的處理,但是發現如果這樣,實際數據有多少層就要做多少次判斷,有沒有一勞永逸的方法呢?

  調試過程中,發現函數的調用特別符合遞歸的規律,通過兩個函數遞歸相互調用的方法可以完美解決這個問題!

    如果爲字典,則調用字典處理函數;

    如果是列表或者元組,則調用列表處理函數;

    如果當前數據類型與當前處理函數相同,則調用自身,一直到遍歷所有數據

示例代碼

  不多說,上代碼,註釋已經寫得比較清晰:

#! /usr/bin/python
# coding:utf-8 
""" 
@author:Bingo.he 
@file: get_target_value.py 
@time: 2017/12/22 
"""
def get_target_value(key, dic, tmp_list):
    """
    :param key: 目標key值
    :param dic: JSON數據
    :param tmp_list: 用於存儲獲取的數據
    :return: list
    """
    if not isinstance(dic, dict) or not isinstance(tmp_list, list):  # 對傳入數據進行格式校驗
        return 'argv[1] not an dict or argv[-1] not an list '

    if key in dic.keys():
        tmp_list.append(dic[key])  # 傳入數據存在則存入tmp_list
    else:
        for value in dic.values():  # 傳入數據不符合則對其value值進行遍歷
            if isinstance(value, dict):
                get_target_value(key, value, tmp_list)  # 傳入數據的value值是字典,則直接調用自身
            elif isinstance(value, (list, tuple)):
                _get_value(key, value, tmp_list)  # 傳入數據的value值是列表或者元組,則調用_get_value
    return tmp_list


def _get_value(key, val, tmp_list):
    for val_ in val:
        if isinstance(val_, dict):  
            get_target_value(key, val_, tmp_list)  # 傳入數據的value值是字典,則調用get_target_value
        elif isinstance(val_, (list, tuple)):
            _get_value(key, val_, tmp_list)   # 傳入數據的value值是列表或者元組,則調用自身

效果圖:

上圖對函數做了簡單的測試,能從很複雜的多重嵌套數據中正常獲取到想要的值

 

編寫該函數時遇到的坑:

初始時,博主將存儲獲取數據的臨時list放到了參數裏面,這樣調用時候就可以少傳一個參數,

def get_target(a, b=[]):
    b.append(a)
    print(b)

get_target(1)

但是後來發現,單次調用的時候不存在問題,但是多次調用的時候,會同時返回上一次調用的值,

可能是python函數本身的一個bug

後來查了很多資料瞭解到,參數默認值,只會在函數聲明是初始化一次,之後不會再初始化

def foo(a=[])和 foo(a=[])的區別:前者是參數默認值,後者是keyword arguments
下面這段代碼定義和調用也是存在細微差別的
def foo(*args, **kargs):
    pass
    
foo(*args, **kargs)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章