'Which data structure to use as an array of dicts?

I need to build a data structure like this one:

{
    key: {k: v for k in range(fixed_small_number)}
    for key in range(fixed_large_number)
}

The thing is I'm building it in an "eclectic" way, where every time get one more item to put in a random k for a random key, i.e. I need random-access, and I need the inner dict to be mutable.

So my question is divided into two:

  1. The recommended type for the outer dict.

  2. The recommended type for the inner dict.

the "best" solution for me would be an array of mutable namedtuples, only this doesn't exist.

I could use a list of namedtuples, and then recreate each one with the new data, but that sounds super-wasteful with the lists not being random-access-efficient and all the rewrites of the same data.

Is there some magical new structure I'm not aware of?

EDIT: example of usage:

for key, k, v in [('a', 1, 2), ('b', 1, 3), ('a', 2, 1), ('a', 3, 1), ('b', 3, 1) ...]:
    my_structre[key][k] = v

EDIT2:

it turns out that lists actually DO support random access



Solution 1:[1]

defaultdict feels right here:

from collections import defaultdict

d = defaultdict(lambda: defaultdict(int))

d[3][4] = 10

If you want fixed-sized lists, defaultdict has you covered:

d = defaultdict(lambda: [None]*fixed_small_number)

d[3][4] = 10
# d[3] is now [None, None, None, None, 10, None, None, ...]

Solution 2:[2]

Given your example:

for key, k, v in [('a', 1, 2), ('b', 1, 3), ('a', 2, 1), ('a', 3, 1), ('b', 3, 1) ...]:
    my_structre[key][k] = v

The solution would indeed be by using defaultdict.

from collections import defaultdict

d = defaultdict(dict)
for key, k, v in [('a', 1, 2), ('b', 1, 3), ('a', 2, 1), ('a', 3, 1), ('b', 3, 1)]:
    d[key][k] = v

Answer:

{'a': {1: 2, 2: 1, 3: 1}, 'b': {1: 3, 3: 1}}

As a function:

def method(iter_of_3_item_iters):
    d = defaultdict(dict)
    for (a, b, c) in iter_of_3_item_iters:
        d[a][b] = c
    return d

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nneonneo
Solution 2