A simple, fast, typed, and tested implementation for a python3.6+ Modifiable Items dictionary. ModifiableItemsDict
extends dict
with the ability to modify keys and values on creation, insertion, and retrieval. This class extends and
maintains the original functionality of the builtin dict
.
In addition to ModifiableItemsDict
, this implementation also includes ModifiableItemsAttrDict
,
a class that inherits from ModifiableItemsDict
and adds attribute-style access to dictionary items.
This means you can access dictionary items as if they were attributes of the object, providing an alternative,
often more readable way to access dictionary items.
Like ModifiableItemsDict
, ModifiableItemsAttrDict
also allows modification of keys and values on creation,
insertion, and retrieval, ensuring consistency and flexibility in handling dictionary items.
ModifiableItemsDict
and ModifiableItemsAttrDict
.ModifiableItemsAttrDict
allows attribute-style access to dictionary items, providing anModifiableItemsDict
and ModifiableItemsAttrDict
run as expected.CaselessDict
ModifiableItemsDict
and ModifiableItemsAttrDict
whichCaselessDict
and CaselessAttrDict
that ignores the case of the keys.pip install modifiable-items-dictionary
The ModifiableItemsDict
and ModifiableItemsAttrDict
classes are part of the modifiable_items_dictionary
module.
They provide advanced dictionary functionalities with additional features for modifying keys and values.
The ModifiableItemsDict
class is a dictionary class that allows modification of keys and values during creation,
insertion, and retrieval. It provides the following features:
from modifiable_items_dictionary import ModifiableItemsDict def _add_1(_value): if isinstance(_value, int): _value += 1 return _value def _case_fold_string(_value): if isinstance(_value, str): _value = _value.casefold() return _value ModifiableItemsDict._key_modifiers = [str.casefold] ModifiableItemsDict._value_modifiers = ( _add_1, _case_fold_string) # Or # ModifiableItemsDict._key_modifiers = staticmethod(str.casefold) # ModifiableItemsDict._value_modifiers = [_case_fold_string, _add_1] modifiable_items_dictionary = ModifiableItemsDict( {"lower": 1, "UPPER": 2}, CamelCase=3, snake_case="FoUR" ) print( modifiable_items_dictionary ) # {'lower': 2, 'upper': 3, 'camelcase': 4, 'snake_case': 'four'} del modifiable_items_dictionary["LOWER"] del modifiable_items_dictionary["UPPER"] modifiable_items_dictionary.pop("SNAKE_CAse") modifiable_items_dictionary["HeLLO"] = 5 print(modifiable_items_dictionary) # {'camelcase': 4, 'hello': 6}
The ModifiableItemsAttrDict
class is an extension of the ModifiableItemsDict
class, inheriting all its features
while adding attribute-style access to dictionary items. This class maintains the same key and value modifiers, ensuring
consistency and flexibility in handling dictionary items.
Like ModifiableItemsDict
, ModifiableItemsAttrDict
is designed with thread safety in mind, making it suitable for use
in multi-threaded applications. It is also fully tested to ensure reliable operation.
In addition to these features, ModifiableItemsAttrDict
offers:
dict.key
instead of dict['key']
. This provides an alternative, often moreThis combination of features makes ModifiableItemsAttrDict
a powerful tool for managing dictionaries in a way that is
both flexible and intuitive, while maintaining the robustness and reliability of the ModifiableItemsDict
class.
import modifiable_items_dictionary def _add_1(_value): if isinstance(_value, int): _value += 1 return _value def _case_fold_string(_value): if isinstance(_value, str): _value = _value.casefold() return _value modifiable_items_dictionary.ModifiableItemsAttrDict._key_modifiers = [ str.casefold ] modifiable_items_dictionary.ModifiableItemsAttrDict._value_modifiers = ( _add_1, _case_fold_string, ) modifiable_items_attr_dict = ( modifiable_items_dictionary.ModifiableItemsAttrDict( {'lower': 1, 'UPPER': 2}, CamelCase=3, snake_case='FoUR' ) ) print( modifiable_items_attr_dict ) # {'lower': 2, 'upper': 3, 'camelcase': 4, 'snake_case': 'four'} # Key-based access del modifiable_items_attr_dict['LOWER'] modifiable_items_attr_dict['HeLLO'] = 5 # Attribute-based access del modifiable_items_attr_dict.UPPER modifiable_items_attr_dict.HeLLO = 6 print(modifiable_items_attr_dict.hELlo) # 6 print(modifiable_items_attr_dict) # {'camelcase': 4, 'hello': 6}
Let's say that there is a .json
file that has Url hosts and their IP address.
Our Goal is to load the json data into a dictionary like structure that will
have it's items modified during creation,
insertion, and retrieval.
This example highlights how to inherit from ModifiableItemsDict
and had key
and value modifiers.
import ipaddress from modifiable_items_dictionary import ModifiableItemsDict class HostDict(ModifiableItemsDict): _key_modifiers = [str.casefold, str.strip] _value_modifiers = [ipaddress.ip_address] # Or # _value_modifiers = @staticmethod(ipaddress.ip_address) browsers = HostDict( { " GooGle.com ": "142.250.69.206", " duckDUCKGo.cOM ": "52.250.42.157", } ) print(browsers) # {'google.com': IPv4Address('142.250.69.206'), 'duckduckgo.com': IPv4Address('52.250.42.157')} _old_browser = browsers.pop(" gOOgle.com ") # or # del host_dict[" GooGle.com "] browsers[" BrAvE.com "] = "2600:9000:234c:5a00:6:d0d2:780:93a1" print(browsers) # {'duckduckgo.com': IPv4Address('52.250.42.157'), 'brave.com': IPv6Address('2600:9000:234c:5a00:6:d0d2:780:93a1')}
It is easy to add Threading to a ModifiableItemsDict
.
NOTE: Since ModifiableItemsDict
is not pickable it does not work with
Multiprocessing. It only works with Multithreading.
import multiprocessing.pool import string import time from modifiable_items_dictionary import ModifiableItemsDict pool = multiprocessing.pool.ThreadPool(10) def _slow_function(x): time.sleep(.05) return x class TimeDictWithThreading(ModifiableItemsDict): _key_modifiers = (_slow_function,) _value_modifiers = (_slow_function,) _map_function = pool.imap_unordered # or if order matters # _map_function = pool.imap class TimeDict(ModifiableItemsDict): _key_modifiers = (_slow_function,) _value_modifiers = (_slow_function,) iterable = {_letter: _index for _index, _letter in enumerate(string.ascii_letters)} # Without Threading start = time.perf_counter() TimeDict(iterable) end = time.perf_counter() print(f"{end - start:.2f} seconds") # 5.54 seconds # With Threading start = time.perf_counter() TimeDictWithThreading(iterable) end = time.perf_counter() print(f"{end - start:.2f} seconds") # 0.64 seconds
This project was inspired by Raymond
Hettinger (rhettinger).
Owner
Contributors
Categories
Products
Application Centric Infrastructure (ACI)Programming Languages
PythonLicense
Code Exchange Community
Get help, share code, and collaborate with other developers in the Code Exchange community.View Community