pythonjsonlistdictionary

I am unable to figure out how to parse through an API response consisting of lists and dictionaries to get details - Python


How can I select all the locations, ratings and names from each result in my list and put it together into variables (names, ratings, locations).

The top 2 results from the List(places_info):

[{'results': [{'location': {'address': '150 Greenwood Ave',
     'country': 'CA',
     'cross_street': 'Dundas St E',
     'formatted_address': '150 Greenwood Ave (Dundas St E), Toronto ON M4L 2R1',
     'locality': 'Toronto',
     'postcode': 'M4L 2R1',
     'region': 'ON'},
    'name': 'Leslieville Farmers Market',
    'rating': 9.1},
   {'location': {'address': '1001 Eastern Ave',
     'country': 'CA',
     'cross_street': 'Woodfield Rd',
     'formatted_address': '1001 Eastern Ave (Woodfield Rd), Toronto ON M4L 1A8',
     'locality': 'Toronto',
     'postcode': 'M4L 1A8',
     'region': 'ON'},
    'name': 'Rorschach Brewing',
    'rating': 8.7},
   {'location': {'address': '1483 Queen St E',
     'country': 'CA',
     'cross_street': '',
     'formatted_address': '1483 Queen St E, Toronto ON M4L 1E2',
     'locality': 'Toronto',
     'postcode': 'M4L 1E2',
     'region': 'ON'},
    'name': 'Chick-N-Joy',
    'rating': 7.6},
   {'location': {'address': '1592 Queen St E',
     'country': 'CA',
     'cross_street': '',
     'formatted_address': '1592 Queen St E, Toronto ON M4L 1G1',
     'locality': 'Toronto',
     'postcode': 'M4L 1G1',
     'region': 'ON'},
    'name': 'Velotique',
    'rating': 7.4},
   {'location': {'address': '6 Coxwell Ave',
     'country': 'CA',
     'cross_street': 'Queen',
     'formatted_address': '6 Coxwell Ave (Queen), Toronto ON M4L 3A7',
     'locality': 'Toronto',
     'postcode': 'M4L 3A7',
     'region': 'ON'},
    'name': 'O Sushi',
    'rating': 7.5},
   {'location': {'address': 'Queen St',
     'country': 'CA',
     'cross_street': 'at Kingston Rd',
     'formatted_address': 'Queen St (at Kingston Rd), Toronto ON M4L 1G7',
     'locality': 'Toronto',
     'postcode': 'M4L 1G7',
     'region': 'ON'},
    'name': 'Woodbine Park',
    'rating': 8.5},
   {'location': {'address': '1374 Queen St E',
     'country': 'CA',
     'cross_street': 'at Greenwood Ave',
     'formatted_address': '1374 Queen St E (at Greenwood Ave), Toronto ON M4L 1C9',
     'locality': 'Toronto',
     'postcode': 'M4L 1C9',
     'region': 'ON'},
    'name': 'The Sidekick',
    'rating': 8.8},
   {'location': {'address': '1636 Queen St E',
     'country': 'CA',
     'cross_street': 'btwn Coxwell Ave. & Kingston Rd.',
     'formatted_address': '1636 Queen St E (btwn Coxwell Ave. & Kingston Rd.), Toronto ON M4L 1G3',
     'locality': 'Toronto',
     'postcode': 'M4L 1G3',
     'region': 'ON'},
    'name': "The Burger's Priest",
    'rating': 7.6},
   {'location': {'address': '1646 Queen St E',
     'country': 'CA',
     'cross_street': 'at Eastern Ave,',
     'formatted_address': '1646 Queen St E (at Eastern Ave,), Toronto ON M4L 1G3',
     'locality': 'Toronto',
     'postcode': 'M4L 1G3',
     'region': 'ON'},
    'name': 'Casa Di Giorgios',
    'rating': 7.4},
   {'location': {'address': '73 Coxwell Ave',
     'country': 'CA',
     'cross_street': 'Dundas St & Coxwell St',
     'formatted_address': '73 Coxwell Ave (Dundas St & Coxwell St), Toronto ON M4L 3B1',
     'locality': 'Toronto',
     'postcode': 'M4L 3B1',
     'region': 'ON'},
    'name': 'British Style Fish & Chips',
    'rating': 7.6}],
  'context': {'geo_bounds': {'circle': {'center': {'latitude': 43.665269,
      'longitude': -79.319796},
     'radius': 1000}}}},
 {'results': [{'location': {'address': '31 Powerhouse St',
     'country': 'CA',
     'cross_street': 'Lansdowne Ave',
     'formatted_address': '31 Powerhouse St (Lansdowne Ave), Toronto ON M6H 0C7',
     'locality': 'Toronto',
     'postcode': 'M6H 0C7',
     'region': 'ON'},
    'name': "Balzac's Coffee Roasters",
    'rating': 8.4},
   {'location': {'address': '330 Geary Ave',
     'country': 'CA',
     'cross_street': 'at Lightbourn Ave.',
     'formatted_address': '330 Geary Ave (at Lightbourn Ave.), Toronto ON M6H 2C7',
     'locality': 'Toronto',
     'postcode': 'M6H 2C7',
     'region': 'ON'},
    'name': 'Rehearsal Factory',
    'rating': 6.7},
   {'location': {'address': '1200 Lansdowne Ave',
     'country': 'CA',
     'cross_street': '',
     'formatted_address': '1200 Lansdowne Ave, Toronto ON M6H 3Z8',
     'locality': 'Toronto',
     'postcode': 'M6H 3Z8',
     'region': 'ON'},
    'name': 'Earlscourt Park Off-Leash Area',
    'rating': 6.2},
   {'location': {'address': '229 Geary Ave',
     'country': 'CA',
     'cross_street': 'at Dufferin St',
     'formatted_address': '229 Geary Ave (at Dufferin St), Toronto ON M6H 2C1',
     'locality': 'Toronto',
     'postcode': 'M6H 2C1',
     'region': 'ON'},
    'name': 'The Greater Good Bar',
    'rating': 8.9},
   {'location': {'address': '1311 Saint Clair Ave W',
     'country': 'CA',
     'cross_street': '',
     'formatted_address': '1311 Saint Clair Ave W, Toronto ON M6E 1C2',
     'locality': 'Toronto',
     'postcode': 'M6E 1C2',
     'region': 'ON'},
    'name': 'Tre Mari Bakery',
    'rating': 9.0},
   {'location': {'address': '1200 Lansdowne Ave',
     'country': 'CA',
     'cross_street': '',
     'formatted_address': '1200 Lansdowne Ave, Toronto ON M6H 3Z8',
     'locality': 'Toronto',
     'postcode': 'M6H 3Z8',
     'region': 'ON'},
    'name': 'Earlscourt Park',
    'rating': 7.5},
   {'location': {'address': '1359 Davenport Rd',
     'country': 'CA',
     'cross_street': '',
     'formatted_address': '1359 Davenport Rd, Toronto ON M6H 2H5',
     'locality': 'Toronto',
     'postcode': 'M6H 2H5',
     'region': 'ON'},
    'name': 'The Sovereign',
    'rating': 7.3},
   {'location': {'address': '217 Geary Ave',
     'country': 'CA',
     'cross_street': '',
     'formatted_address': '217 Geary Ave, Toronto ON M6H 2C1',
     'locality': 'Toronto',
     'postcode': 'M6H 2C1',
     'region': 'ON'},
    'name': 'Parallel',
    'rating': 8.2},
   {'location': {'address': '1256 Saint Clair Ave W',
     'country': 'CA',
     'cross_street': 'at Boon Ave.',
     'formatted_address': '1256 Saint Clair Ave W (at Boon Ave.), Toronto ON M6E 1B9',
     'locality': 'Toronto',
     'postcode': 'M6E 1B9',
     'region': 'ON'},
    'name': 'Rio 40 Restaurant',
    'rating': 8.4},
   {'location': {'address': '229 Geary Ave',
     'country': 'CA',
     'cross_street': '',
     'formatted_address': '229 Geary Ave, Toronto ON M6H 2C1',
     'locality': 'Toronto',
     'postcode': 'M6H 2C1',
     'region': 'ON'},
    'name': 'North Of Brooklyn Pizzeria',
    'rating': 7.3}],
  'context': {'geo_bounds': {'circle': {'center': {'latitude': 43.67142,
      'longitude': -79.445947},
     'radius': 1000}}}},
....

I want to be able to do something like the code below but get all the values for each result instead of only the values in the first list. There are too many lists to manually write the index for each.

results = [place['results'] for place in places_info]
names = [place[0]['name'] for place in results]
ratings = [place[0]['ratings'] for place in results]
locations = [place[0]['locations'] for place in results]

How can I do this?


Solution

  • Because the data structure has arrays at two levels, it'll be easier to use a nested for loop to flatten the results into a single array.

    flat_results = []
    for place in places:
        results = place['results']
        for result in results:
            flat_results.append(result)
    
    #array notation alternative
    alt_flat_results = [result for result in place['results'] for place in places]
    

    This will give you a single array containing all of the result objects nested in the response. Then you can get whatever field you like with something like the following:

    locations = [result['location'] for result in flat_results]