2

I have some JSON that I want to loop over (simplified):

{
"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"
    }
}

The dates are values that I do not know beforehand and change every day, so I want to loop over them and print the date with the open, high, low, etc. So far all I have been able to do is loop over the dates and print them, but when I tried to get the other values, being new to JSON reading, I failed with the following code:

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)

I also tried doing:

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

Instead of nesting, but it nevertheless did not work. On both tries, I get the same error:

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

So anyone know how to loop through all the dates and get out the open, high, low, etc from them?

The full version of the JSON is available here.

5 Answers 5

3

You can achieve this by treating it as a dictionary. Try the following as your loop, and you will be able to extract the results you want:

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("-------------")

This is a snippet of what it will output, for a date:

Date: 2018-07-02
1. open: 75.7500
2. high: 76.1517
3. low: 74.7800
4. close: 75.7700
5. volume: 3518838
-------------
Sign up to request clarification or add additional context in comments.

2 Comments

Nice, worked exactly the way I wanted it to. What is the use of the .item function?
@R.Vij It turns the dictionary into a list of tuples, making it easily iterable, and allows us to separate into keys and values very easily. Glad I could help!
1

I took json_data['Time Series (Daily)'] and assigned it to its own variable to make it easier to reference in the for loop.

Then when looping through you have to reference that variable to access values inside the date keys.

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()

Comments

1

Hy, well the major subject here isn't JSON's itself, but dictionaries, a built-in type in Python. I don't know exactlly what you want to do with this data, but a way to acess then is by acessing the methods that comes with dictionaries. Like dict.keys(), dict.items() and dict.values(), you could look up for some of the documentation for this. I will let an example for how to acess the data, hope it helps.

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))

Going really ahead of this, you could write a function that prints the value if isn't a dict, like:

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

See ya!

Comments

0

This may be just my style, but I prefer this approach:

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]))

This way, you've already assigned values to the open, high, low... in one line and it's easy to use moving forward.

I also made it print all the values on newlines (with indents) in one line of code, this makes for less code spaghetti than doing a print() for each value. Although this is limited in it's uses but pretty efficient for debugging if you know the structure.

1 Comment

I get an unexpected EOF while parsing. Why?
0

I like to write code that is what is called data-driven because that often makes it easier to change later on.

Here's how that could be done in this situation:

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()

Output:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.