0

I'm trying to create a dictionary of dictionaries like this:

food = {"Broccoli": {"Taste": "Bad", "Smell": "Bad"},
        "Strawberry": {"Taste": "Good", "Smell": "Good"}}

But I am populating it from an SQL table. So I've pulled the SQL table into an SQL object called "result". And then I got the column names like this:

nutCol = [i[0] for i in result.description]

The table has about 40 characteristics, so it is quite long.

I can do this...

foodList = {}
for id, food in enumerate(result):
    addMe = {str(food[1]): {nutCol[id + 2]: food[2], nulCol[idx + 3]: 
            food[3] ...}}
    foodList.update(addMe)

But this of course would look horrible and take a while to write. And I'm still working out how I want to build this whole thing so it's possible I'll need to change it a few times...which could get extremely tedious.

Is there a DRY way of doing this?

Aro
  • 494
  • 5
  • 20
  • See: http://stackoverflow.com/questions/38987/how-to-merge-two-python-dictionaries-in-a-single-expression – jrd1 Apr 28 '17 at 03:11
  • See that doesn't quite work for me because it's a dictionary of dictionaries. It's not just adding one key/pair at a time. I need to be able to say something like foodList["Chicken"]["Protein"] – Aro Apr 28 '17 at 03:13
  • 1
    Your suggested code is not making a dictionary of dictionaries ... is there a particular field you think of as the "id" that you want to associate the other properties with? – donkopotamus Apr 28 '17 at 03:14

3 Answers3

2

In order to make solution position independent you can make use of dict1.update(dict2). This simply merges dict2 with dict1.

In our case since we have dict of dict, we can use dict['key'] as dict1 and simply add any additional key,value pair as dict2.

Here is an example.

food = {"Broccoli": {"Taste": "Bad", "Smell": "Bad"}, 
        "Strawberry": {"Taste": "Good", "Smell": "Good"}}

addthis = {'foo':'bar'}

Suppose you want to add addthis dict to food['strawberry'] , we can simply use,

food["Strawberry"].update(addthis)

Getting result:

>>> food
{'Strawberry': {'Taste': 'Good', 'foo': 'bar', 'Smell': 'Good'},'Broccoli': {'Taste': 'Bad', 'Smell': 'Bad'}}
>>>  
Anil_M
  • 10,893
  • 6
  • 47
  • 74
1

addMe = {str(food[1]):dict(zip(nutCol[2:],food[2:]))}

zip will take two (or more) lists of items and pair the elements, then you can pass the result to dict to turn the pairs into a dictionary.

Josep Valls
  • 5,483
  • 2
  • 33
  • 67
1

Assuming that column 0 is what you wish to use as your key, and you do wish to build a dictionary of dictionaries, then its:

detail_names = [col[0] for col in result.description[1:]]
foodList = {row[0]: dict(zip(detail_names, row[1:]))
            for row in result}

Generalising, if column k is your identity then its:

foodList = {row[k]: {col[0]: row[i]
                     for i, col in enumerate(result.description) if i != k}
            for row in result}

(Here each sub dictionary is all columns other than column k)

donkopotamus
  • 22,114
  • 2
  • 48
  • 60