2

Here is the JSON data I have:

{
  "response": {
    "status": {
      "version": "4.2",
      "code": 0,
      "message": "Success"
    },
    "artists": [
      {
        "name": "Taylor Swift",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:19614945368"
          }
        ],
        "hotttnesss": 0.99956,
        "id": "ARS54I31187FB46721"
      },
      {
        "name": "Ed Sheeran",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:9189674485"
          }
        ],
        "hotttnesss": 0.994265,
        "id": "ARSDWSZ122ECCB706A"
      },
      {
        "name": "Calvin Harris",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:19366141168"
          }
        ],
        "hotttnesss": 0.990559,
        "id": "ARJRB241187FB556A3"
      },
      {
        "name": "Sam Smith",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:313595788739120"
          }
        ],
        "hotttnesss": 0.988203,
        "id": "ARUZM8A11C8A41519C"
      },
      {
        "name": "Maroon 5",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:5330548481"
          }
        ],
        "hotttnesss": 0.984929,
        "id": "ARF5M7Q1187FB501E8"
      },
      {
        "name": "Sia",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:10959868407"
          }
        ],
        "hotttnesss": 0.983516,
        "id": "AR6ENUY1187B994158"
      },
      {
        "name": "David Guetta",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:7619396355"
          }
        ],
        "hotttnesss": 0.982656,
        "id": "ARH2QI91187FB3788D"
      },
      {
        "name": "Ellie Goulding",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:135027136641"
          }
        ],
        "hotttnesss": 0.981786,
        "id": "ARKTTJV12592CDA07F"
      },
      {
        "name": "Wiz Khalifa",
        "foreign_ids": [
          {
            "catalog": "facebook",
            "foreign_id": "facebook:artist:12138756141"
          }
        ],
        "hotttnesss": 0.978492,
        "id": "ARN0GFV1187FB508CC"
      },
      {
        "name": "Ariana Grande",
        "hotttnesss": 0.978074,
        "id": "AROHQCR13244CF7152"
      }
    ]
  }
}

I'm trying to parse "catalog" and "foreign_id". Here is my code:

for item in data['response']['artists']:
    for row in item['foreign_ids']:
        print row['catalog'], row['foreign_id']

The results are:

facebook facebook:artist:19614945368
facebook facebook:artist:9189674485
facebook facebook:artist:19366141168
facebook facebook:artist:313595788739120
facebook facebook:artist:5330548481
facebook facebook:artist:10959868407
facebook facebook:artist:7619396355
facebook facebook:artist:135027136641
facebook facebook:artist:12138756141

KeyError
Traceback (most recent call last)
<ipython-input-224-cbc34d6d831e> in <module>()
      1 for item in data['response']['artists']:
----> 2     for row in item['foreign_ids']:
      3         print row['catalog'], row['foreign_id']

KeyError: 'foreign_ids'

I think I know why; the last data row does not have "foreign_ids". How would I include an if statement to help me avoid this error? For example, the code outputs "None" when there is no array value called "foreign_ids".

4 Answers 4

2

You have to check to see if that column exists before you attempt to iterate over it. This approach is known as "look before you leap". Here we're using get, since it will return None by default and not raise the KeyError.

for item in data['response']['artists']:
    if item.get('foreign_ids'):
        for row in item['foreign_ids']:
            print row['catalog'], row['foreign_id']

Alternatively, you could employ a default value through get which supplies an empty list to iterate over instead.

for item in data['response']['artists']:
    for row in item.get('foreign_ids', []):
        print row['catalog'], row['foreign_id']

In both cases, you have to check to see if that key exists. The code you have assumes that it's always present, which is definitely not the case.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you all for the nice suggestions!
1

Instead of an if statement (which is perfectly valid), you can use a try/except block:

for item in data['response']['artists']:
    try:    
        for row in item['foreign_ids']:
            print row['catalog'], row['foreign_id']
    except KeyError as Ex:
        print "{} not found in {}".format(Ex,item)

This gives:

...
facebook facebook:artist:7619396355
facebook facebook:artist:135027136641
facebook facebook:artist:12138756141
'foreign_ids' not found in {'id': 'AROHQCR13244CF7152', 'name': 'Ariana Grande', 'hotttnesss': 0.978074}

which IMO is cleaner since it explicitly acknowledges the problem and acts on it. Instead of print, you can do an alternate action like a log.

Comments

1

You could check to see if the key is in that part of the JSON object by doing:

if 'somekey' in somPartOfTheJson:
    jsonObj = json.loads(jsonStr)

    for item in jsonObj['response']['artists']:
        if 'foreign_ids' in item:
            for row in item['foreign_ids']:
                if 'catalog' in row and 'foreign_id' in row:
                    print row['catalog'], row['foreign_id']

Comments

0
if 'foreign_ids' not in item:
    continue
for row in item['foreign_ids']:
....

2 Comments

I'd have written it the other way (as in, if 'foreign_ids' in item:), but this suffices.
I prefer the continue method as it alleviates using lots of indentation :). To each their own.

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.