python - Why didn't I get a KeyError when the key did not exist?


Keywords:python 


Question: 

In the following test data, I am trying to append key 'x' value to the list ls. My question is why I didn't get a KeyError when looping through the first row of the data. Clearly, the first row does not contain the key 'x'. Originally I thought I had to use Try/Except to avoid getting an error when looping through the data, but it seems that Try/Except is not needed.

Could anyone help me understand why a KeyError is not generated here?

data = [{u'xyz': []},
        {u'xyz': [{u'x' : 2,
                   u'y' : 3, 
                   u'z' : 4}]}]

ls = []

for item in data:
    ddd = item['xyz']
    print ddd

    for d in ddd:
        ls.append(d['x'])

ls

output:

[]
[{u'y': 3, u'x': 2, u'z': 4}]

[2]

2 Answers: 

A loop over nothing doesn't run:

>>> for item in []:
...     print item
...
>>>

so

data = [{u'xyz': []},
            ...       ]


# first time through
for item in data:
    ddd = item['xyz']

    # ddd is an empty list

    for d in ddd:
        # this doesn't run, therefore no KeyError
        ls.append(d['x'])

Try/Except is needed if you want to catch a KeyError, if you want to avoid one you can either do:

if 'x' in d:  # test if 'x' is a key in d

or

d.get('x')    # returns the value, or None
 

The first row is an empty list, there's no KeyError because there's no dictionary in it. So the loop:

for d in ddd:

is not entered. Try change the first row to:

data = [{u'xyz': [{}]},

You would see the KeyError as expected.