简体   繁体   English

在 Python 3 中迭代多级 json/dictionaries

[英]Iterate through multi level json/dictionaries in Python 3

I am fetching data from an api我正在从 api 获取数据

data = json.loads(api_response.content)

which returns返回

{
  'NKE': {
    'quote': {
      'symbol': 'NKE',
      'companyName': 'NIKE, Inc.',
      'primaryExchange': 'New York Stock Exchange',
      'calculationPrice': 'close',
      'open': 101.14,
      'openTime': 1578321000670,
      'close': 101.83,
      'closeTime': 1578344409251,
      'high': 101.84,
      'low': 100.869,
      'latestPrice': 101.83,
      'latestSource': 'Close',
      'latestTime': 'January 6, 2020',
      'latestUpdate': 1578344409251,
      'latestVolume': 4608458,
      'iexRealtimePrice': 0,
      'iexRealtimeSize': 0,
      'iexLastUpdated': 0,
      'delayedPrice': 101.83,
      'delayedPriceTime': 1578346947002,
      'extendedPrice': 101.99,
      'extendedChange': 0.16,
      'extendedChangePercent': 0.00157,
      'extendedPriceTime': 1578400716493,
      'previousClose': 101.92,
      'previousVolume': 4542003,
      'change': -0.09,
      'changePercent': -0.00088,
      'volume': 0,
      'iexMarketPercent': None,
      'iexVolume': 0,
      'avgTotalVolume': 5776147,
      'iexBidPrice': 0,
      'iexBidSize': 0,
      'iexAskPrice': 0,
      'iexAskSize': 0,
      'marketCap': 158959684900,
      'peRatio': 34.88,
      'week52High': 102.21,
      'week52Low': 74.3,
      'ytdChange': -0.0045,
      'lastTradeTime': 1578344409241,
      'isUSMarketOpen': False
    }
  },
  'UAA': {
    'quote': {
      'symbol': 'UAA',
      'companyName': 'Under Armour, Inc.',
      'primaryExchange': 'New York Stock Exchange',
      'calculationPrice': 'close',
      'open': 21.51,
      'openTime': 1578321000404,
      'close': 20.44,
      'closeTime': 1578344686271,
      'high': 21.53,
      'low': 20.35,
      'latestPrice': 20.44,
      'latestSource': 'Close',
      'latestTime': 'January 6, 2020',
      'latestUpdate': 1578344686271,
      'latestVolume': 11132892,
      'iexRealtimePrice': 0,
      'iexRealtimeSize': 0,
      'iexLastUpdated': 0,
      'delayedPrice': 20.49,
      'delayedPriceTime': 1578347272279,
      'extendedPrice': 0,
      'extendedChange': None,
      'extendedChangePercent': None,
      'extendedPriceTime': 1578356330039,
      'previousClose': 21.85,
      'previousVolume': 4596587,
      'change': -1.41,
      'changePercent': -0.06453,
      'volume': 0,
      'iexMarketPercent': None,
      'iexVolume': 0,
      'avgTotalVolume': 4329339,
      'iexBidPrice': 0,
      'iexBidSize': 0,
      'iexAskPrice': 0,
      'iexAskSize': 0,
      'marketCap': 9230009040,
      'peRatio': 82.55,
      'week52High': 27.72,
      'week52Low': 16.74,
      'ytdChange': -0.126054,
      'lastTradeTime': 1578344399983,
      'isUSMarketOpen': False
    }
  },

my aim is to access elements on the third and final level like symbol, companyName and latestPrice and add it to a database我的目标是访问第三级也是最后一级的元素,如符号、公司名称和最新价格,并将其添加到数据库中

dic_data = {
            "symbol": data['symbol'] , 
            "latestPrice": data['latestPrice'] , 
            "companyName":  data['companyName'], 
            "week52High": data['week52High'] , 
            "week52Low": data['week52Low'] , 
            "ytdChange": data['ytdChange'] ,
            "latestTime":  data['latestTime'],  
            "changePercent": data['changePercent'] , 
            }
)

how can I loop through data and access the last level of the dictionary?如何遍历数据并访问字典的最后一级?

For looping through all quote dictionaries do:要循环遍历所有quote字典,请执行以下操作:

for key in data:
    data_quote = data[key]['quote']
    for quote_key in data_quote:
        # Do your stuff with data_quote[quote_key]

Try this:尝试这个:

li = []
for i in data:
    for j in data[i]:
        li.append({'symbol': data[i][j]['symbol'], "latestPrice": data[i][j]['latestPrice']})
print(li)

This will get you the output:这将为您提供输出:

output = [
    {
        "symbol": data[company]['quote']['symbol'],
        "latestPrice": data[company]['quote']['latestPrice'],
        "companyName": data[company]['quote']['companyName'],
        "week52High": data[company]['quote']['week52High'],
        "week52Low": data[company]['quote']['week52Low'],
        "ytdChange": data[company]['quote']['ytdChange'],
        "latestTime": data[company]['quote']['latestTime'],
        "changePercent": data[company]['quote']['changePercent'],
    } for company in data
]

Nice answers have already been posted.已经发布了很好的答案。 I am just posting a recursive method.我只是发布一个递归方法。 This is just to bring out the variety of ways it can be solved.这只是为了带出可以解决的各种方法。

Please be warned about cautions raised against Recursive methods everywhere.请注意对递归方法的警告无处不在。 However recursion is a nice method if you don't know beforehand how many for loops are needed to solve the problem但是,如果您事先不知道需要多少个 for 循环来解决问题,那么递归是一个不错的方法

My code is as below.我的代码如下。 I have assumed that data is the name of the nested dictionary that you have.我假设 data 是您拥有的嵌套字典的名称。 ReturnedDict is the name of the dictionary that you finally want. ReturnedDict是您最终想要的字典的名称。

from collections import defaultdict
LookUpList = ['symbol' , 'latestPrice','companyName', 'week52High' , 'week52Low' , 'ytdChange' ,'latestTime', 'changePercent']
ReturnedDict = defaultdict(list)

def ReachALevelAndGrabValue(DictionaryToAssess):
    for everyKey in DictionaryToAssess:
        if isinstance(DictionaryToAssess[everyKey], dict):
            ReachALevelAndGrabValue(DictionaryToAssess[everyKey])
        else:
            if everyKey in LookUpList:
                ReturnedDict[everyKey].append(DictionaryToAssess[everyKey])


ReachALevelAndGrabValue(data)
print(ReturnedDict)

This gives me the printout as below.这给了我如下的打印输出。

defaultdict(<class 'list'>, {'symbol': ['NKE', 'UAA'], 'companyName': ['NIKE, Inc.', 'Under Armour, Inc.'], 'latestPrice': [101.83, 20.44], 'latestTime': ['January 6, 2020', 'January 6, 2020'], 'changePercent': [-0.00088, -0.06453], 'week52High': [102.21, 27.72], 'week52Low': [74.3, 16.74], 'ytdChange': [-0.0045, -0.126054]})

Is this what you wanted?这是你想要的吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM