oso9817
oso9817

Reputation: 117

Retrieve one value from a list of dicts based on another value in the dict

I have a dictionary created from a JSON document:

{
  "response": {
  "version":"0.1",
  "termsofService":"http://www.wunderground.com/weather/api/d/terms.html",
  "features": {
  "hourly": 1
  }
    }
    ,
"hourly_forecast": [
    {
    "FCTTIME": {
    "hour": "22","hour_padded": "22","min": "00","min_unpadded": "0","sec": "0","year": "2017","mon": "3","mon_padded": "03","mon_abbrev": "Mar","mday": "8","mday_padded": "08","yday": "66","isdst": "0","epoch": "1489028400","pretty": "10:00 PM EST on March 08, 2017","civil": "10:00 PM","month_name": "March","month_name_abbrev": "Mar","weekday_name": "Wednesday","weekday_name_night": "Wednesday Night","weekday_name_abbrev": "Wed","weekday_name_unlang": "Wednesday","weekday_name_night_unlang": "Wednesday Night","ampm": "PM","tz": "","age": "","UTCDATE": ""
    },
    "temp": {"english": "50", "metric": "10"},
    "dewpoint": {"english": "20", "metric": "-7"},
    "condition": "Partly Cloudy",
    "icon": "partlycloudy",
    "icon_url":"http://icons.wxug.com/i/c/k/nt_partlycloudy.gif",
    "fctcode": "2",
    "sky": "6",
    "wspd": {"english": "29", "metric": "47"},
    "wdir": {"dir": "W", "degrees": "262"},
    "wx": "Clear/Wind",
    "uvi": "0",
    "humidity": "30",
    "windchill": {"english": "-9999", "metric": "-9999"},
    "heatindex": {"english": "-9999", "metric": "-9999"},
    "feelslike": {"english": "50", "metric": "10"},
    "qpf": {"english": "0.0", "metric": "0"},
    "snow": {"english": "0.0", "metric": "0"},
    "pop": "0",
    "mslp": {"english": "30.01", "metric": "1016"}
    }
    ,
    {
    "FCTTIME": {
    "hour": "23","hour_padded": "23","min": "00","min_unpadded": "0","sec": "0","year": "2017","mon": "3","mon_padded": "03","mon_abbrev": "Mar","mday": "8","mday_padded": "08","yday": "66","isdst": "0","epoch": "1489032000","pretty": "11:00 PM EST on March 08, 2017","civil": "11:00 PM","month_name": "March","month_name_abbrev": "Mar","weekday_name": "Wednesday","weekday_name_night": "Wednesday Night","weekday_name_abbrev": "Wed","weekday_name_unlang": "Wednesday","weekday_name_night_unlang": "Wednesday Night","ampm": "PM","tz": "","age": "","UTCDATE": ""
    },
    "temp": {"english": "49", "metric": "9"},
    "dewpoint": {"english": "20", "metric": "-7"},
    "condition": "Partly Cloudy",
    "icon": "partlycloudy",
    "icon_url":"http://icons.wxug.com/i/c/k/nt_partlycloudy.gif",
    "fctcode": "2",
    "sky": "5",
    "wspd": {"english": "24", "metric": "39"},
    "wdir": {"dir": "W", "degrees": "263"},
    "wx": "Clear/Wind",
    "uvi": "0",
    "humidity": "32",
    "windchill": {"english": "-9999", "metric": "-9999"},
    "heatindex": {"english": "-9999", "metric": "-9999"},
    "feelslike": {"english": "49", "metric": "9"},
    "qpf": {"english": "0.0", "metric": "0"},
    "snow": {"english": "0.0", "metric": "0"},
    "pop": "0",
    "mslp": {"english": "30.02", "metric": "1017"}
    }

With this data, I want to get the 'temp' value from the first dictionary in the 'hourly_forecast' list whose 'hour' is '22'.

I know I could use the code below to get the first element:

j_hour['hourly_forecast'][0]['temp']['english']

... but this data always changes based on the time I retrieve it, so if it was 1 PM it would be "hour": "13" first up.

Basically I need help with pulling the 'temp' data based on the 'hour' value with a list that is always changing, so I can't just pull it based on element sequence.

To sum it up, I'm stuck printing the 'temp' key from the 'hour' I want.

Upvotes: 2

Views: 43

Answers (1)

schesis
schesis

Reputation: 59108

A good way to approach this is to narrow your search down step by step until you get just the piece of information you're looking for.

First, use a list comprehension to get all the english temperatures, regardless of hour:

>>> [d['temp']['english'] for d in j_hour['hourly_forecast']]
['50', '49', ...]

Then restrict it to cases where the hour is '22':

>>> [d['temp']['english'] for d in j_hour['hourly_forecast']
...                       if d['FCTTIME']['hour'] == '22']
['50']

Now you've got the temperature you want, wrapped in a list. If you convert the list comprehension to a generator expression by replacing the brackets [] with parentheses (), you can call next() on it to get the first (and only, in this case) item:

>>> next(d['temp']['english'] for d in j_hour['hourly_forecast']
...                           if d['FCTTIME']['hour'] == '22')
'50'

... et voilà!

Upvotes: 2

Related Questions