【问题标题】:How to loop over values in JSON data?如何遍历 JSON 数据中的值?
【发布时间】:2019-04-23 13:01:01
【问题描述】:

我有一些 JSON 想要循环(简化):

{
"Meta Data": {
    "1. Information": "Daily Prices (open, high, low, close) and Volumes",
    "2. Symbol": "TGT",
    "3. Last Refreshed": "2018-11-20 14:50:52",
    "4. Output Size": "Compact",
    "5. Time Zone": "US/Eastern"
},
"Time Series (Daily)": {
    "2018-11-20": {
        "1. open": "67.9900",
        "2. high": "71.5000",
        "3. low": "66.1500",
        "4. close": "69.6800",
        "5. volume": "15573611"
    },
    "2018-11-19": {
        "1. open": "79.9300",
        "2. high": "80.4000",
        "3. low": "77.5607",
        "4. close": "77.7900",
        "5. volume": "9126929"
    }
}

日期是我事先不知道的值并且每​​天都在变化,所以我想循环它们并用开盘价、最高价、最低价等打印日期。到目前为止,我所能做的就是循环覆盖日期并打印它们,但是当我尝试获取其他值时,对于 JSON 读取来说是新手,我使用以下代码失败了:

import urllib.parse
import requests

code = 'TGT'
main_api = ('https://www.alphavantage.co/query? function=TIME_SERIES_DAILY&symbol=' +
            code + '&apikey=RYFJGY3O92BUEVW4')
url  = main_api + urllib.parse.urlencode({'NYSE': code})

json_data = requests.get(url).json()
#print(json_data)

for item in json_data['Time Series (Daily)']:
    print(item)
    for item in json_data[item]:
        print(item)

我也试过这样做:

for v in json_data:
    print(v['1. open'])

而不是嵌套,但它仍然不起作用。 在这两次尝试中,我都得到了同样的错误:

Traceback (most recent call last):
   File "jsonreader.py", line 26, in <module>
      for item in item['Time Series (Daily)'][item]:
TypeError: string indices must be integers

所以有人知道如何遍历所有日期并从中找出开盘价、最高价、最低价等吗?

完整版 JSON 可用here

【问题讨论】:

    标签: python json loops nested-loops


    【解决方案1】:

    我取了json_data['Time Series (Daily)'] 并将其分配给它自己的变量,以便更容易在 for 循环中引用。

    然后在循环时必须引用该变量才能访问日期键中的值。

    data = json_data['Time Series (Daily)']
    
    for item in data:
        print(item)
        print("open", data[item]["1. open"])
        print("high", data[item]["2. high"])
        print("low", data[item]["3. low"])
        print("close", data[item]["4. close"])
        print("vloume", data[item]["5. volume"])
        print()
    

    【讨论】:

      【解决方案2】:

      您可以通过将其视为字典来实现此目的。尝试以下作为您的循环,您将能够提取您想要的结果:

      for key,value in json_data['Time Series (Daily)'].items():
              print("Date: " + key) #This prints the Date
              print("1. open: " + value["1. open"])
              print("2. high: " + value["2. high"])
              print("3. low: " + value["3. low"])
              print("4. close: " + value["4. close"])
              print("5. volume: " + value["5. volume"])
              print("-------------")
      

      这是它将输出的内容的 sn-p,用于日期:

      Date: 2018-07-02
      1. open: 75.7500
      2. high: 76.1517
      3. low: 74.7800
      4. close: 75.7700
      5. volume: 3518838
      -------------
      

      【讨论】:

      • 很好,完全按照我想要的方式工作。 .item 函数有什么用?
      • @R.Vij 它将字典转换为元组列表,使其易于迭代,并允许我们非常轻松地分离为键和值。很高兴我能帮上忙!
      【解决方案3】:

      这可能只是我的风格,但我更喜欢这种方法:

      for item in json_data['Time Series (Daily)']:
          open, high, low, close, volume = sorted(item).values()
          print('\n\t'.join([item.keys()[0], open, high, low, close, volume]))
      

      这样,您已经在一行中为开盘价、最高价、最低价...分配了值,并且易于使用。

      我还让它在一行代码中打印换行符上的所有值(带有缩进),这使得代码意大利面条比为每个值执行print() 更少。虽然这在它的用途上是有限的,但如果你知道它的结构,那么它对调试非常有效。

      【讨论】:

      • 我在解析时得到一个意外的 EOF。为什么?
      【解决方案4】:

      我喜欢编写称为data-driven 的代码,因为这通常使以后更容易更改。

      在这种情况下可以这样做:

      SERIES_KEY = 'Time Series (Daily)'
      VALUE_KEYS = '1. open', '2. high', '3. low', '4. close', '5. volume'
      longest_key = max(len(key) for key in VALUE_KEYS)
      
      daily = json_data[SERIES_KEY]
      for date, values in sorted(daily.items()):
          print(date)
          for key in VALUE_KEYS:
              print('  {:{width}} :  {}'.format(key, values[key], width=longest_key))
          print()
      

      输出:

      2018-11-19
        1. open   :  79.9300
        2. high   :  80.4000
        3. low    :  77.5607
        4. close  :  77.7900
        5. volume :  9126929
      
      2018-11-20
        1. open   :  67.9900
        2. high   :  71.5000
        3. low    :  66.1500
        4. close  :  69.6800
        5. volume :  15573611
      

      【讨论】:

        【解决方案5】:

        嘿,这里的主要主题不是 JSON 本身,而是字典,Python 中的一种内置类型。我不知道你想用这些数据做什么,但是一种访问方法是访问字典附带的方法。像 dict.keys()、dict.items() 和 dict.values() 一样,您可以查找一些相关文档。我将举例说明如何访问数据,希望对您有所帮助。

        url=requests.get('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=TGT&apikey=RYFJGY3O92BUEVW4')
        url_json = url.json() # This data is actually of dict type
        for k,j in url_json['Time Series (Daily)'].items():
            print(k)
            for m, n in j.items(): # This data are a nested dictionary
                print('{} : {}'.format(m, n))
        

        在此之前,您可以编写一个函数,如果不是 dict,则打印该值,例如:

        def print_values(dictionary):
            if isinstance(dictionary, dict):
                for k, v in dictionary.items():
                    print(k)
                    print_values(v)
            else:
                print(dictionary)
        

        再见!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-15
          • 2020-12-21
          • 1970-01-01
          • 2021-02-02
          • 2021-04-06
          • 2012-06-07
          相关资源
          最近更新 更多