0

I have a very large .json converted into a string, containing numerous cities/countries.

I'd like to extract the information of the city depending on the user's choice of country (London is just an example).

For example, if the Country the user inputed was: UK, the following information would be extracted from the string:

I'm not too sure on how I could possibly achieve this due to my inexperience, but am aware that it would require an if statement. My progress so far:

Country = raw_input('Country: ')
if 'UK' in string:
    ???
Enigmatic
  • 3,902
  • 6
  • 26
  • 48
  • Do you know how to parse the JSON using the `json` module? – FamousJameous Sep 28 '16 at 17:38
  • @FamousJameous Hmm, No, I'll have a look I guess. – Enigmatic Sep 28 '16 at 17:41
  • Here's the link for future reference: https://docs.python.org/2.7/library/json.html – FamousJameous Sep 28 '16 at 17:42
  • This is the opposite of what you want to do. You want to make a dictionary so you can do lookups on `Country`, not convert all the json to a string. As it is, your json is invalid though so it's not possible to give an accurate answer. – roganjosh Sep 28 '16 at 17:43
  • @roganjosh I posted the full json at the bottom: http://api.wunderground.com/api/a8c3e5ce8970ae66/conditions/q/London.json – Enigmatic Sep 28 '16 at 17:44
  • Oops, I missed that part at the very bottom. Ok, so you are only interested in `results` from that json? – roganjosh Sep 28 '16 at 17:48
  • @roganjosh Yes, I believe so :) – Enigmatic Sep 28 '16 at 17:49
  • Actually, not possible. Several entries in `results` have the same country and different states etc. You couldn't determine the expected result from just `country` alone – roganjosh Sep 28 '16 at 17:50
  • Hmm, Okay. That's understandable. But how might it be possible for the small section of the JSON I provided in the question, just simply differentiating the UK and US.? I don't actually mind if it returns multiple results. – Enigmatic Sep 28 '16 at 17:54
  • That is your *complete* json? Assuming that "results" just has many entries and that's all you cut off... the structure is the same? – roganjosh Sep 28 '16 at 18:11
  • If that JSON string is meant to be a list of dictionaries, it's missing the opening and closing square brackets. – John Gordon Sep 28 '16 at 18:12
  • @JohnGordon The full JSON is at the bottom – Enigmatic Sep 28 '16 at 18:14
  • @ThatOnePythonNoob If you're going to post a sample of the data format, it's in your best interest to make sure it's an _accurate_ sample. People are much less willing to help if you make them click every link and chase down every reference. – John Gordon Sep 28 '16 at 18:20
  • @JohnGordon I have done as requested. Thought it was a little too much to post. – Enigmatic Sep 28 '16 at 18:22
  • @ThatOnePythonNoob It's okay to post a limited summary, but omitting the outer dictionary from your summary made the data appear to have a different structure, which made it harder for us to accurately answer. – John Gordon Sep 28 '16 at 18:28
  • @ThatOnePythonNoob No, I nearly have an answer for you to close this – roganjosh Sep 28 '16 at 18:36
  • @ThatOnePythonNoob Yeah, don't repost, just edit the question (as you appear to have done). – John Gordon Sep 28 '16 at 18:46

3 Answers3

1

The initial response wasn't great because a few of us overlooked the raw JSON. However, you did provide it so in future it would be better to make it more obvious that the snippet you showed had a more complete (and valid) counterpart.

That said, I would load the data into a dictionary and do something like:

import json

json_string = """{
  "response": {
  "version":"0.1",
  "termsofService":"http://www.wunderground.com/weather/api/d/terms.html",
  "features": {
  "conditions": 1
  }
        , "results": [
        {
        "name": "London",
        "city": "London",
        "state": "AR",
        "country": "US",
        "country_iso3166":"US",
        "country_name":"USA",
        "zmw": "72847.1.99999",
        "l": "/q/zmw:72847.1.99999"
        }
        ,
        {
        "name": "London",
        "city": "London",
        "state": "KY",
        "country": "US",
        "country_iso3166":"US",
        "country_name":"USA",
        "zmw": "40741.1.99999",
        "l": "/q/zmw:40741.1.99999"
        }
        ,
        {
        "name": "London",
        "city": "London",
        "state": "MN",
        "country": "US",
        "country_iso3166":"US",
        "country_name":"USA",
        "zmw": "56036.3.99999",
        "l": "/q/zmw:56036.3.99999"
        }
        ,
        {
        "name": "London",
        "city": "London",
        "state": "OH",
        "country": "US",
        "country_iso3166":"US",
        "country_name":"USA",
        "zmw": "43140.1.99999",
        "l": "/q/zmw:43140.1.99999"
        }
        ,
        {
        "name": "London",
        "city": "London",
        "state": "ON",
        "country": "CA",
        "country_iso3166":"CA",
        "country_name":"Canada",
        "zmw": "00000.1.71623",
        "l": "/q/zmw:00000.1.71623"
        }
        ,
        {
        "name": "London",
        "city": "London",
        "state": "TX",
        "country": "US",
        "country_iso3166":"US",
        "country_name":"USA",
        "zmw": "76854.1.99999",
        "l": "/q/zmw:76854.1.99999"
        }
        ,
        {
        "name": "London",
        "city": "London",
        "state": "",
        "country": "UK",
        "country_iso3166":"GB",
        "country_name":"United Kingdom",
        "zmw": "00000.1.03772",
        "l": "/q/zmw:00000.1.03772"
        }
        ,
        {
        "name": "London",
        "city": "London",
        "state": "WV",
        "country": "US",
        "country_iso3166":"US",
        "country_name":"USA",
        "zmw": "25126.1.99999",
        "l": "/q/zmw:25126.1.99999"
        }
        ]
    }
}"""

json_object = json.loads(json_string)

world_dict = {}
for item in json_object['response']['results']:
    item_country = item['country']
    in_dict = world_dict.get(item_country)
    if in_dict:
        world_dict[item_country].extend([item])
    else:
        world_dict[item_country] = [item]

country = raw_input('Country: ')

response = world_dict.get(country)
if response:
    for item in response:
        print item
else:
    print "Not a valid country"

EDIT: Based on comment to use URL rather than a JSON string.

import requests

url = 'http://api.wunderground.com/api/a8c3e5ce8970ae66/conditions/q/London.json'

data = requests.get(url).json()


world_dict = {}
for item in data['response']['results']:
    item_country = item['country']
    in_dict = world_dict.get(item_country)
    if in_dict:
        world_dict[item_country].extend([item])
    else:
        world_dict[item_country] = [item]

country = raw_input('Country: ')

response = world_dict.get(country)
if response:
    for item in response:
        print item
else:
    print "Not a valid country"
roganjosh
  • 12,594
  • 4
  • 29
  • 46
  • 1
    @ThatOnePythonNoob you're very welcome :) I updated so that it will reject an incorrect country name. Don't be disheartened by the difficulties before; like I said, you _did_ post an accurate json structure, it was just very easy to gloss over being right at the bottom and with an invalid snippet at the top. If this code has solved your problem, I would appreciate you marking it correct (clicking the tick next to the answer) so that others don't think it's still not answered. – roganjosh Sep 28 '16 at 18:50
  • Would it be possible to change `json_string` to the API link (http://api.wunderground.com/api/a8c3e5ce8970ae66/conditions/q/London.json) and then convert it to a string? Would the program still work? – Enigmatic Sep 28 '16 at 18:55
  • @ThatOnePythonNoob It works _better_ using the API; we don't have (what was almost certainly) a JSON response, converted to a string, and back again. Normally this should be a different question but I edited my answer in this instance. Please do mark this as correct because it will save people time now thinking that this is unanswered. – roganjosh Sep 28 '16 at 19:05
0
import json

country = raw_input('Country: ')

jsondata = "the large json string mentioned in your post"

info = json.loads(jsondata)

for item in info:
    if item['country'] == country:
        print item
John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • Isn't it `for item in info['results']`? – roganjosh Sep 28 '16 at 17:59
  • @John Gordon, That literally printed 10000 lines – Enigmatic Sep 28 '16 at 18:03
  • OK then, limit it to just the information you want: `print item['name'], item['city'], item['state'], etc...` – John Gordon Sep 28 '16 at 18:05
  • @roganjosh Why do you think a `results` key would be present? I don't see anything like that in the post, and `json.loads` wouldn't create it. – John Gordon Sep 28 '16 at 18:11
  • Then you, like me(!), didn't spot the link at the very bottom of the question – roganjosh Sep 28 '16 at 18:12
  • Aha. Well, if poster can't be bothered to post correct info in the question, then goodbye and good luck. – John Gordon Sep 28 '16 at 18:14
  • @JohnGordon I think it was an innocent mistake tbh. The info was there but I too didn't see it because of the snippet provided at the top of the question :( – roganjosh Sep 28 '16 at 18:18
  • @JohnGordon 1) The correct info is posted in the question 2) I apologize that you weren't able to spot it, I'll post the whole info instead of a link next time to make it clearer. My mistake... – Enigmatic Sep 28 '16 at 18:42
0

You can try this. Might still want to consider some user input errors in your code. For example, str.strip() and capital sensitive.

import json
input_country = raw_input('Please enter country:')
with open('London.json') as fp:
    london_json = fp.read()
    london = json.loads(london_json)
    for item in london["response"]["results"]:
        if item['country'] == input_country:
            print json.dumps(item, indent = 2)
  • Thanks for the suggestion! When running, I currently get the error: IOError: [Errno 2] No such file or directory: 'http://api.wunderground.com/api/a8c3e5ce8970ae66/conditions/q/London.json' Any ideas? – Enigmatic Sep 28 '16 at 18:09