3

I am trying to create a nested dictionary from a mysql query but I am getting a key error

result = {}

for i, q in enumerate(query):

    result['data'][i]['firstName'] = q.first_name
    result['data'][i]['lastName'] = q.last_name
    result['data'][i]['email'] = q.email

error

KeyError: 'data'

desired result

result = {
    'data': {
        0: {'firstName': ''...}
        1: {'firstName': ''...}
        2: {'firstName': ''...}
    }
}
Rudie
  • 49,688
  • 40
  • 128
  • 172
user3071933
  • 167
  • 3
  • 10
  • you want the keys to be the integers from 0 to `len(result)`? why not use a list? – jpwagner Dec 05 '13 at 20:32
  • Why do you use `'data'` if you don't want to have it in `result`? – Lev Levitsky Dec 05 '13 at 20:32
  • 1
    You should look up dictionaries in the docs – keyser Dec 05 '13 at 20:32
  • @KEYSER Be easy with OP, this is a typical assumption error for any beginner to assume flat dict assignment would create nested dict. If everyone needs to learn from docs (which we didnt refer), then why SOF ;) – user2390183 Dec 05 '13 at 21:37
  • possible duplicate of [What's the best way to initialize a dict of dicts in Python?](http://stackoverflow.com/questions/651794/whats-the-best-way-to-initialize-a-dict-of-dicts-in-python) – timfeirg Oct 10 '14 at 08:43

4 Answers4

9

You wanted to create a nested dictionary

result = {} will create an assignment for a flat dictionary, whose items can have any values like "string", "int", "list" or "dict"

For this flat assignment

python knows what to do for result["first"]

If you want "first" also to be another dictionary you need to tell Python by an assingment result['first'] = {}.

otherwise, Python raises "KeyError"

I think you are looking for this :)

>>> from collections import defaultdict
>>> mydict = lambda: defaultdict(mydict)
>>> result = mydict()
>>> result['Python']['rules']['the world'] = "Yes I Agree"
>>> result['Python']['rules']['the world']
'Yes I Agree'
Eyal.D
  • 450
  • 3
  • 17
user2390183
  • 959
  • 8
  • 16
1
result = {}
result['data'] = {}

for i, q in enumerate(query):
    result['data']['i'] = {}
    result['data'][i]['firstName'] = q.first_name
    result['data'][i]['lastName'] = q.last_name
    result['data'][i]['email'] = q.email

Alternatively, you can use you own class which adds the extra dicts automatically

class AutoDict(dict):
    def __missing__(self, k):
        self[k] = AutoDict()
        return self[k]

result = AutoDict()

for i, q in enumerate(query):
    result['data'][i]['firstName'] = q.first_name
    result['data'][i]['lastName'] = q.last_name
    result['data'][i]['email'] = q.email
John La Rooy
  • 281,034
  • 50
  • 354
  • 495
0

result['data'] does exist. So you cannot add data to it.

Try this out at the start:

result = {'data': []};
qwertynl
  • 3,842
  • 1
  • 20
  • 43
0

You have to create the key data first:

result = {}
result['data'] = {}

for i, q in enumerate(query):
    result['data'][i] = {}
    result['data'][i]['firstName'] = q.first_name
    result['data'][i]['lastName'] = q.last_name
    result['data'][i]['email'] = q.email
Hyperboreus
  • 31,109
  • 9
  • 45
  • 84