HakariDo
HakariDo

Reputation: 287

Values from nested dictionary

UPDATE: How to access values in a nested dictionary, where one need two keys, the first to find the inner dict, the second to find the value at that key2.

How does python access values from a nested dictionary, with two keys? Or must I restructure the dictionary / create separate dictionaries?

For example, I want to access

List item

config = {
    'g7': {},
    'd5': {},
    'a9': {},
}    
config['g7']['append_dir_to_filename'] = 1,
config['g7']['raw_file'] = ('cr2', 'jpg', 'mp4'),

config['d5']['append_dir_to_filename'] = 1,
config['d5']['raw_file'] = ('nef', 'jpg', 'avi'),

config['a9']['append_dir_to_filename'] = 1,
config['a9']['raw_file'] = ('mp4', 'jpg', 'avi')

In respect of structuring nested dictionaries, this would be the complexity per one (1) camera. There are 10 camera types in total and the goal is to rename, sort, extract info, etc. from mediafiles from these cameras in one bulk swipe:

config['d5']['append_dir_to_filename'] = 1
config['d5']['device_name'] = 'Nikon-D5'
config['d5']['raw_file'] = ('nef', 'jpg', 'avi')
config['d5']['sup_file'] = ('jpg', 'wav')
config['d5']['to_else_file'] = ('avi')
config['d5']['timestamp'] = ('lwt')
config['d5']['md5'] = 1
config['d5']['code1'] = 'FAR'
config['d5']['gps'] = 1

Upvotes: 1

Views: 1509

Answers (2)

Reblochon Masque
Reblochon Masque

Reputation: 36662

You access the values the same way you assigned them:

print(config['g7']['append_dir_to_filename'])
print(config['d5']['append_dir_to_filename'])
print(config['a9']['raw_file'])
...

To access the values residing inside a nested dictionary, you need two keys: the first key1 to find the inner dict, and the second to find the value at key2.

To access the values for the key ['append_dir_to_filename'] for all "fist keys" such as g7, d5, a9, you must iterate over config, which gets you key1, and read the values at the desired location:

for key1 in config:
    print(config[key1]['append_dir_to_filename'])

Edit:

(thanks to Suggestions from @MartijnPieters in the comments) if all you are going to do is look at the values, it is preferable to loop over dict.values() instead and save the repeated config[key1]:

for inner in config.values():
    print(inner['append_dir_to_filename'])

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1121824

You have nested dictionaries. Your outer dictionary keys all refer to another dictionary, which then has keys too. Python lets you chain the expressions there.

So to access a specific inner value, you first access the outer dictionary:

config['d5']

This produces another dictionary object, and you just apply another [...] key access expression to that result:

config['d5']['raw_file']

If you need to access the same key on all nested dictionaries, you need to loop:

for nested in config.values():
    print(nested['append_dir_to_filename'])

Here nested is a reference to each of the nested dictionaries in the config dictionary.

A more complex example could be printing out all outer keys for which a condition on the values in the inner dictionary holds true. Like printing all keys for which 'append_dir_to_filename' is 1:

for name, nested in config.items():
    if nested['append_dir_to_filename'] == 1:
        print(name)

dict.items() lets you iterate over all (key, nested dictionary) pairs, then simply treat that nested value as another dictionary object again to test the values.

If all you are trying to do is track information on a homogenous set of properties (all the same values for multiple entries), consider using a custom class (where you can add methods) or a collections.namedtuple() generated class to track those fields:

from collections import namedtuple

ConfigEntry = namedtuple('ConfigEntry', 'append_dir_to_filename raw_file')

config = {
    'g7': ConfigEntry(1, ('cr2', 'jpg', 'mp4')),
    'd5': ConfigEntry(1, ('nef', 'jpg', 'avi')),
    'a9': ConfigEntry(1, ('mp4', 'jpg', 'avi')),
}    

# printing a specific value
print(config['d5'].raw_file)

# printing the same value for each entry
for entry in config.values():
    print(entry.append_dir_to_filename)

Upvotes: 2

Related Questions