原文鏈接:
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)