No project description provided
Project description
modifiable-items-dict
A simple, fast, typed, and tested implementation for a python3.6+ Modifiable Items dictionary. ModifiableItemsDict
extends dict
with the ability to modify key's and value's on creation, insertion, and retrieval.
This class extends and maintains the original functionality of the builtin dict
.
Key Features:
- Easy: Flexable and easy to add Key and/or Value modifiers to the
ModifiableItemsDict
- Great Developer Experience: Being fully typed makes it great for editor support.
- Fully Tested: Our test suit fully tests the functionality to ensure that
ModifiableItemsDict
runs as expected. - There is More!!!:
- CaselessDict:
CaselessDict
extendsModifiableItemsDict
which is aCaselessDict
which ignores the case of the keys.
- CaselessDict:
Installation
pip install modifiable-items-dictionary
Simple Example
from modifiable_items_dict import ModifiableItemsDict
def _lower(_key):
if isinstance(_key, str):
_key = _key.lower()
return _key
def _add_1(_value):
if isinstance(_value, int):
_value += 1
return _value
ModifiableItemsDict._key_modifiers = [_lower]
ModifiableItemsDict._value_modifiers = (_lower, _add_1)
# Or
# ModifiableItemsDict._key_modifiers = staticmethod(_lower)
# ModifiableItemsDict._value_modifiers = [_lower, _add_1]
modifiable_items_dict = ModifiableItemsDict({"lower":1, "UPPER":2 }, CamelCase=3, snake_case="FoUR")
print(modifiable_items_dict) # {'lower': 2, 'upper': 3, 'camelcase': 4, 'snake_case': 'four'}
del modifiable_items_dict["LOWER"]
del modifiable_items_dict["UPPER"]
modifiable_items_dict.pop("SNAKE_CAse")
modifiable_items_dict["HeLLO"] = 5
print(modifiable_items_dict) # {'camelcase': 4, 'hello': 6}
Example
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 contextlib
import ipaddress
import json
from typing import Any, Union
from modifiable_items_dict import ModifiableItemsDict
def _strip(_value: Any):
if isinstance(_value, str):
_value = _value.strip()
return _value
return _value
def _case_fold(_value: Any) -> Any:
if isinstance(_value, str):
_case_folded_string: str = _value.casefold()
return _case_folded_string
return _value
def _to_ipaddress(_value: Any) -> Any:
if isinstance(_value, str):
with contextlib.suppress(ValueError):
_ip_address: Union[
ipaddress.IPv4Address, ipaddress.IPv6Address
] = ipaddress.ip_address(_value)
return _ip_address
return _value
class HostDict(ModifiableItemsDict):
_key_modifiers = [_strip, _case_fold]
_value_modifiers = [_to_ipaddress]
# Or
# _value_modifiers = @staticmethod(_to_ipaddress)
_json: str = '{" GooGle.com ": "142.250.69.206", " duckDUCKGo.cOM ": "52.250.42.157"}'
host_dict: HostDict = json.loads(_json, object_hook=HostDict)
print(host_dict) # {'google.com': IPv4Address('142.250.69.206'), 'duckduckgo.com': IPv4Address('52.250.42.157')}
_old_browser = host_dict.pop(" gOOgle.com ")
# or
# del host_dict[" GooGle.com "]
host_dict[" BrAvE.com "] = "2600:9000:234c:5a00:6:d0d2:780:93a1"
print(host_dict) # {'duckduckgo.com': IPv4Address('52.250.42.157'), 'brave.com': IPv6Address('2600:9000:234c:5a00:6:d0d2:780:93a1')}
Threading Example
It is easy to add Threading to a ModifiableItemsDict
.
NOTE: Since ModifiableItemsDict
is not pickable it does not work with Multiprocessing.
from multiprocessing.pool import ThreadPool as Pool
from string import ascii_letters
from time import perf_counter, sleep
from modifiable_items_dict.modifiable_items_dict import ModifiableItemsDict
pool = Pool(10)
def _slow_function(x):
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(ascii_letters)}
# Without Threading
start = perf_counter()
TimeDict(iterable)
end = perf_counter()
print(f"{end - start:.2f} seconds") # 5.54 seconds
# With Threading
start = perf_counter()
TimeDictWithThreading(iterable)
end = perf_counter()
print(f"{end - start:.2f} seconds") # 0.64 seconds
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for modifiable-items-dictionary-1.0.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | f338d2c1fae639bc606941f2e077782bc772a378e2b63377f80876268f94221f |
|
MD5 | f58647bb5bc31c17e3f75154a8f18f48 |
|
BLAKE2b-256 | 1c0d056cb320acc41d019e502cabfdc220daa7bb9a3655e56ad7c794b890c5a6 |
Hashes for modifiable_items_dictionary-1.0.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 134fbe955f2ad9bc6382726fb2b396f6db1207efc4d69921007faa4e1b59b45f |
|
MD5 | f83a78ffe9d63ef9f7e7b466367f793c |
|
BLAKE2b-256 | e1c0db6168474c2fd74022351dc4f9791d620dcc7faa6056e68bf4f1d1617bfa |