MappingTools. Do stuff with Mappings
Project description
MappingTools
This library provides utility functions for manipulating and transforming data structures which have or include Mapping-like characteristics. Including inverting dictionaries, converting class like objects to dictionaries, creating nested defaultdicts, and unwrapping complex objects.
Package |
|
Tools |
|
CI/CD |
|
Scans |
|
Usage
Transformers
distinct
Yields distinct values for a specified key across multiple mappings.
from mappingtools import distinct
mappings = [
{'a': 1, 'b': 2},
{'a': 2, 'b': 3},
{'a': 1, 'b': 4}
]
distinct_values = list(distinct('a', *mappings))
print(distinct_values)
# Output: [1, 2]
keep
Yields subsets of mappings by retaining only the specified keys.
from mappingtools import keep
mappings = [
{'a': 1, 'b': 2, 'c': 3},
{'a': 4, 'b': 5, 'd': 6}
]
keys_to_keep = ['a', 'b']
result = list(keep(keys_to_keep, *mappings))
# result: [{'a': 1, 'b': 2}, {'a': 4, 'b': 5}]
remove
Yields mappings with specified keys removed. It takes an iterable of keys and multiple mappings, and returns a generator of mappings with those keys excluded.
from mappingtools import remove
mappings = [
{'a': 1, 'b': 2, 'c': 3},
{'a': 4, 'b': 5, 'd': 6}
]
keys_to_remove = ['a', 'b']
result = list(remove(keys_to_remove, *mappings))
# result: [{'c': 3}, {'d': 6}]
inverse
Swaps keys and values in a dictionary.
from mappingtools import inverse
original_mapping = {'a': {1, 2}, 'b': {3}}
inverted_mapping = inverse(original_mapping)
print(inverted_mapping)
# Output: defaultdict(<class 'set'>, {1: {'a'}, 2: {'a'}, 3: {'b'}})
strictify
Strictify function applies a strict structural conversion to an object using optional converters for keys and values.
from mappingtools import strictify
def uppercase_key(key):
return key.upper()
def double_value(value):
return value * 2
data = {'a': 1, 'b': 2}
result = strictify(data, key_converter=uppercase_key, value_converter=double_value)
print(result)
# Output: {'A': 2, 'B': 4}
simplify
Converts objects to strictly structured dictionaries.
from collections import Counter
from dataclasses import dataclass
from datetime import datetime
from typing import Mapping
from mappingtools import simplify
data = {'key1': 'value1', 'key2': ['item1', 'item2']}
simplified_data = simplify(data)
print(simplified_data)
# Output: {'key1': 'value1', 'key2': ['item1', 'item2']}
counter = Counter({'a': 1, 'b': 2})
print(counter)
# Output: Counter({'b': 2, 'a': 1})
simplified_counter = simplify(counter)
print(simplified_counter)
# Output: {'a': 1, 'b': 2}
@dataclass
class SampleDataClass:
a: int
b: int
aa: str
bb: str
c: list[int]
d: Mapping
e: datetime
sample_datetime = datetime(2024, 7, 22, 21, 42, 17, 314159)
sample_dataclass = SampleDataClass(1, 2, '11', '22', [1, 2], {'aaa': 111, 'bbb': '222'}, sample_datetime)
print(sample_dataclass)
# Output: SampleDataClass(a=1, b=2, aa='11', bb='22', c=[1, 2], d={'aaa': 111, 'bbb': '222'}, e=datetime.datetime(2024, 7, 22, 21, 42, 17, 314159))
simplified_sample_dataclass = simplify(sample_dataclass)
print(simplified_sample_dataclass)
# Output: {'a': 1, 'aa': '11', 'b': 2, 'bb': '22', 'c': [1, 2], 'd': {'aaa': 111, 'bbb': '222'}, 'e': datetime.datetime(2024, 7, 22, 21, 42, 17, 314159)}
listify
Transforms complex objects into a list of dictionaries with key and value pairs.
from mappingtools import listify
wrapped_data = {'key1': {'subkey': 'value'}, 'key2': ['item1', 'item2']}
unwrapped_data = listify(wrapped_data)
print(unwrapped_data)
# Output: [{'key': 'key1', 'value': [{'key': 'subkey', 'value': 'value'}]}, {'key': 'key2', 'value': ['item1', 'item2']}]
stream
Takes a mapping and an optional item factory function, and generates items from the mapping. If the item factory is provided, it applies the factory to each key-value pair before yielding.
from collections import namedtuple
from mappingtools import stream
def custom_factory(key, value):
return f"{key}: {value}"
my_mapping = {'a': 1, 'b': 2, 'c': 3}
for item in stream(my_mapping, custom_factory):
print(item)
# Output:
# a: 1
# b: 2
# c: 3
MyTuple = namedtuple('MyTuple', ['key', 'value'])
data = {'a': 1, 'b': 2}
for item in stream(data, MyTuple):
print(item)
# Output:
# MyTuple(key='a', value=1)
# MyTuple(key='b', value=2)
def record(k, v):
return {'key': k, 'value': v}
for item in stream(data, record):
print(item)
# output:
# {'key': 'a', 'value': 1}
# {'key': 'b', 'value': 2}
stream_dict_records
generates dictionary records from a given mapping, where each record contains a key-value pair from the mapping with customizable key and value names.
from mappingtools import stream_dict_records
mapping = {'a': 1, 'b': 2}
records = stream_dict_records(mapping, key_name='letter', value_name='number')
for record in records:
print(record)
# Output:
# {'letter': 'a', 'number': 1}
# {'letter': 'b', 'number': 2}
Collectors
nested_defaultdict
Creates a nested defaultdict with specified depth and factory.
from mappingtools import nested_defaultdict
nested_dd = nested_defaultdict(1, list)
nested_dd[0][1].append('value')
print(nested_dd)
# Output: defaultdict(<function nested_defaultdict.<locals>.factory at ...>, {0: defaultdict(<function nested_defaultdict.<locals>.factory at ...>, {1: ['value']})})
CategoryCounter
The CategoryCounter class extends a dictionary to count occurrences of data items categorized by multiple categories. It maintains a total count of all data items and allows categorization using direct values or functions.
from mappingtools import CategoryCounter
counter = CategoryCounter()
for fruit in ['apple', 'banana', 'apple']:
counter.update({fruit: 1}, type='fruit', char_count=len(fruit), unique_char_count=len(set(fruit)))
print(counter.total)
# Output: Counter({'apple': 2, 'banana': 1})
print(counter)
# Output: CategoryCounter({'type': defaultdict(<class 'collections.Counter'>, {'fruit': Counter({'apple': 2, 'banana': 1})}), 'char_count': defaultdict(<class 'collections.Counter'>, {5: Counter({'apple': 2}), 6: Counter({'banana': 1})}), 'unique_char_count': defaultdict(<class 'collections.Counter'>, {4: Counter({'apple': 2}), 3: Counter({'banana': 1})})})
MappingCollector
A class designed to collect key-value pairs into an internal mapping based on different modes. It supports modes like ALL, COUNT, DISTINCT, FIRST, and LAST, each dictating how key-value pairs are collected.
from mappingtools import MappingCollector, MappingCollectorMode
collector = MappingCollector(MappingCollectorMode.ALL)
collector.add('a', 1)
collector.add('a', 2)
collector.collect([('b', 3), ('b', 4)])
print(collector.mapping)
# Output: {'a': [1, 2], 'b': [3, 4]}
Development
Ruff
ruff check src
Test
Standard (cobertura) XML Coverage Report
python -m pytest tests -n auto --cov=src --cov-branch --doctest-modules --cov-report=xml
HTML Coverage Report
python -m pytest tests -n auto --cov=src --cov-branch --doctest-modules --cov-report=html
Project details
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 mappingtools-0.2.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d2c7c748c84dcb260d078bf3224b3f7b125eebf71e56843c03e930737dd38ed9 |
|
MD5 | f6c971bb99d6e67e11a4a330f759dfaa |
|
BLAKE2b-256 | 263f09e129b750ed4d5b54f194ff414e07aa24eba374e4c784258414cf7a8b36 |