0

I'm new with Python, coming from Perl where I've used something like this very often:

#!/usr/bin/env perl
  
my %d;
my $a = 12; $b = 14; $c = 16;

$d{$a}{$b}{$c} = 42;

print($d{$a}{$b}{$c});  # 42

How can fill a dictionary in python e.g. in a loop

If I try this with Python, I've got a KeyError

a = 12
b = 14
c = 16

my_dict[a][b][c] = 42  # KeyError

Is this the only way?

if a in my_dict:
    if b in my_dict[a]:
        my_dict[a][b][c] = 42
    else:
        my_dict[a][b] = {}
        my_dict[a][b][c] = 42
else:
    my_dict[a] = {}
    my_dict[a][b] = {}
    my_dict[a][b][c] = 42
Gusiph
  • 11
  • See https://stackoverflow.com/questions/635483/what-is-the-best-way-to-implement-nested-dictionaries – Thierry Lathuille Jan 01 '21 at 12:00
  • That doesn't seem to be a `dict()`, IMHO. It looks more like a multidimensional array instead. – accdias Jan 01 '21 at 12:02
  • Does this answer your question? [What is the best way to implement nested dictionaries?](https://stackoverflow.com/questions/635483/what-is-the-best-way-to-implement-nested-dictionaries) – J. M. Arnold Jan 01 '21 at 12:08
  • Your Perl code starts with an empty dict, your python code is explicitly built not to. Which case do you want? – MisterMiyagi Jan 01 '21 at 13:31

2 Answers2

3

You may use dict.setdefault(key, default_value)

my_dict = {}
my_dict.setdefault(a, {}).setdefault(b, {}).setdefault(c, 42)
print(my_dict)  # {12: {14: {16: 42}}}

my_dict = {a: {}}
my_dict.setdefault(a, {}).setdefault(b, {}).setdefault(c, 42)
print(my_dict)  # {12: {14: {16: 42}}}

my_dict = {a: {b: {}}}
my_dict.setdefault(a, {}).setdefault(b, {}).setdefault(c, 42)
print(my_dict)  # {12: {14: {16: 42}}}
azro
  • 35,213
  • 7
  • 25
  • 55
0

it is actually better to use deafaultdict instead for this specific use case (it is a nested default dict inspired from this answer):

from collections import defaultdict 

def nested_dict():
    return defaultdict(nested_dict)

my_dict = defaultdict(nested_dict)

a = 12
b = 14
c = 16

my_dict[a][b][c] = 42  # no KeyError
my_dict[a][b][c] 
>>> 42
adir abargil
  • 3,810
  • 1
  • 10
  • 17