TypeError: 'NoneType' object is not subscriptable even though checking the var with an if condition and setting it to a static value otherwise

Question:

I am trying to write a prototype for web scraping. My problem is that I get the error in the title when duetpartner = track['duet']['handle'] is null or of NoneType.

The thing is I already made a check for it and I set it to a static value if it is None:

def create_song_list(track):
   if track['duet']['handle'] is not None:
       duetpartner = track['duet']['handle']
    else:
       duetpartner= 'Solo'

return {
        'Duet_partner': duetpartner
    }

I call create_song_list from within a array.

If more code is required to reproduce I shall supply it, I try to keep it minimal.

The simple solution got expired from a similar question, but still it’s of NoneType for me…: Discord.py TypeError: 'NoneType' object is not subscriptable

UPDATE 1:

Adding or track['duet'] condition doesn’t help…

Asked By: Sir Muffington

||

Answers:

This may help you to understand what’s going on. Let’s have 3 dictionaries:

d1 = {'foo': 'banana'}
d2 = {'duet': {'foo': 'banana'}}
d3 = {'duet': {'handle': 'banana'}}

Now we’re going to find out if a dictionary has a ‘duet’ key and if its value (which we assume is another dictionary) has a ‘handle’ key:

for d in d1, d2, d3:
    print(d.get('duet', dict()).get('handle'))

This gives:

None
None
banana

…which, hopefully, make sense.

This means that the function in the original question can be changed thus:

def create_song_list(track):
    v = track.get('duet', {'handle': 'Solo'}).get('handle', 'Solo')
    return {'Duet_partner': v}

Of course, this will only work if track is a dictionary and the value associated with duet is also a dictionary.

Therefore, an extremely robust approach could be:

def create_song_list(track):
    if isinstance(track, dict):
        if (duet := track.get('duet')) is not None:
            if isinstance(duet, dict):
                if (handle := duet.get('handle')) is not None:
                    return {'Duet_partner': handle}

    return {'Duet_partner': 'Solo'}
Answered By: Fred

You can change your code something like –

def create_song_list(track):
   if track['duet'] is not None and track['duet']['handle'] is not None:
       duetpartner = track['duet']['handle']
    else:
       duetpartner= 'Solo'

return {
        'Duet_partner': duetpartner
    }
Answered By: Rajkumar Hajgude