2

I would like to have a nested dictionary with a list of values that are attached to the sub-key. Can't get the sub-key to recognise.

month = {}
    for row in date:
        month.setdefault(row[1],{row[0]: []})
        month[row[0]].append(row[4])

print(month[main_key][sub_key])

I expect a list of values to be populated out through the appending method. However, I keep getting a keyError.

The desired output:

{'row[1]': {'row[0]' :[row[4], row[4], row[4]],
            'row[0]' :[row[4], row[4], row[4]]}}
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
Susan
  • 51
  • 1
  • 10

2 Answers2

4

Here's a simple example of what I think you are trying to achieve:

>>> rows = [[1,2,3], [1,2,4], [1,3,3], [1,3,5], [2,3,9], [2,3,5]]
>>> ret = {}
>>> for row in rows:
...     ret.setdefault(row[0], {}).setdefault(row[1], []).append(row[2])
...
>>> ret
{1: {2: [3, 4], 3: [3, 5]}, 2: {3: [9, 5]}}

How does it work? For each row:

  1. We look for row[0] in ret keys. If it is not present, we add the pair (row[0], {}) to the dict, {} being the nested dict. It it is present, we continue.
  2. The value row[1] is the key of the nested dict. We look for it in ret[row[0]] (the first setdefault return): if it is not present, we add an empty list.
  3. We add the value row[2] to the list ret[row[0]][row[1]]

Remember that:

ret.setdefault(row[0], value_if_absent).func()

Means:

if row[0] not in ret:
    ret[row[0]] = value_if_absent

ret[row[0]].func()

Usaully, value_if_absent is a container and func is one of append, extend, update, ... methods. But func may also be a setdefault to create a new container if needed.

jferard
  • 7,835
  • 2
  • 22
  • 35
  • Thanks bud! I got it already but someone deleted my answer. ): Got to get used to the rules in here. Nonetheless, thank you so much, I get a clearer picture with all your explanation. – Susan Apr 18 '19 at 15:45
  • @Susan Glad to help! BTW, answering your own question is not forbidden. I don't know why your answer was deleted. Check [the rules](https://stackoverflow.com/help/deleted-answers). – jferard Apr 18 '19 at 19:44
0

Let's follow the statements in the block of the for-loop.

The first is:

month.setdefault(row[1], {row[0]: []})

This will set a value of {row[0]: []} (dictionary) for the key row[1] where the key hasn't been inserted in month.

The next statement is:

month[row[0]].append(row[4])

It appends row[4] to a list retrieved from month with the key row[0]. This line should error given that even when the key exists in month, the value it is paired with is a dictionary and not a list.

That line should be written as:

month[row[1]][row[0]].append(row[4])

month[row[1]] retrieves the dictionary paired with key row[1] which is then indexed to access the list paired with row[0].

Oluwafemi Sule
  • 36,144
  • 1
  • 56
  • 81
  • I kind of get it, it still gives me the same error. I want to set fixed keys so doing setdefault for both keys works. Nonetheless, thank you so much! – Susan Apr 17 '19 at 07:31
  • I should have stated my desire output clearly, my bad. – Susan Apr 17 '19 at 07:32