JP Vossen via plug on 2 Jul 2021 12:51:43 -0700 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
[PLUG] Python nested dict data structure |
If I want to read multiple files, and build a data structure like this by adding different keys and values at different times, and/or incrementing an existing numerical value: ``` {'Acme Inc': {'region': 'US', 'counter': 3}} ``` In Perl, but using Pythonic syntax, this would auto-instantiate and Just Work: ``` dict = {} company = 'Acme Inc' dict[company]['region'] = 'US' dict[company]['counter'] += ave ``` Clean, and simple...except that Perl's syntax for nested data structures is virtually unreadable and really hard to write, for me at least. Overall I'm liking Python, but there are some things, like this, that are hurting my head. In Python it's really easy to create that structure at one time, but that is NOT how most of my use-cases work. I'm always pulling fields out of 2-3 different files and building a data structure in pieces over time. Like company and region are in 1 file, and a whole bunch of records containing something I want to count are in another file(s), with the 'company' key to link them. This works in Python 3 and 2 (sad to say I still have old nodes with only Python2): ``` #!/usr/bin/env python3 # dict.py--do I REALLY have to do all this crap just for NESTED dicts!? dict = {} # Add Nested Key/Value pair to dict def add_nstkv(dict, key, subkey, value): if key not in dict: # Key must exist or error dict[key] = {} # Create empty sub-dict dict[key][subkey] = value # Add value # Add/inc_nstkv a value in a nested dict def inc_nstkv(dict, key, subkey, value): if key not in dict: # Parent key must exist or error dict[key] = {} # Create empty sub-dict if subkey not in dict[key]: # Subkey must exist or error dict[key][subkey] = value # Add value else: dict[key][subkey] += value # inc_nstkv company = 'Acme Inc' add_nstkv(dict, company, 'region', 'US') # Does: dict[company]['region'] = val inc_nstkv(dict, company, 'counter', 1) # Does: dict[company]['counter'] += val inc_nstkv(dict, company, 'counter', 2) print(dict) ``` Output: ``` $ ./dict.py {'Acme Inc': {'region': 'US', 'counter': 3}} ``` I've tried `dict = defaultdict()` and `dict = defaultdict(int)` but both fail since I have mixed string and int values. I've tried all kinds of other crazy stuff and nothing else worked either. Most Google results are too-trivial `d[k] = v` and don't help with nested structs. Do I *really* have to write all that extra code every time I want to do something this simple? Or am I missing something? Later, JP -- ------------------------------------------------------------------- JP Vossen, CISSP | http://www.jpsdomain.org/ | http://bashcookbook.com/ ___________________________________________________________________________ Philadelphia Linux Users Group -- http://www.phillylinux.org Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce General Discussion -- http://lists.phillylinux.org/mailman/listinfo/plug