Skip to main content

decomply allows unified processing of nested dictionaries

Project description

decomply

decomply (decomposeApply) is a short utility package, providing functionality to traverse nested dictionaries (or any enumerable object) and apply a custom function on their values.

Supports also lists, using their indexes as key. Additionally, custom handlers can be supplied to extend support to more types.

Example:

Consider a dictionary like this
input_data = {
    "First Layer": {
        "Second layer": 3,
        "Second layer 2nd element": 4
    },
    "First layer 2nd element": -1
}

Suppose you want to increment the numbers by 1. Then you can use

Decomply(
  apply=lambda _, item: item + 1
  ).decomply(input_data)

Output

{
  "First Layer": {
      "Second layer": 4,
      "Second layer 2nd element": 5
  },
  "First layer 2nd element": 0
}

decomply will traverse the dictionary, stopping at certain points. Then it will apply the desired function on the value at hand and "repeat" the process. In a sense, it decomposes the object into a partition and then applies a function on each part, hence the name decomposeApply, in short decomply

Install

pip install decomply

API

Decomply

The constructor's signature is

def __init__(
    self,
    traverse: callable = lambda trace, item: True,
    apply: callable = lambda trace, item: item,
    delete: callable = lambda trace, item: str(trace[-1]).startswith("_"),
    handlers: set[EnumerableHandler] = None
):

Decomply accepts 4 parameters, each with a default value. The first 3 parameters are callables, which all receive two parameters:

trace: a list of keys, reflecting the path to traverse to the current item
item: the current value

The callables are

apply: lambda: trace, item: item

apply is the function to be applied on the single items. It defaults to returning the original item

traverse: lambda: trace, item: True

traverse allows to specify whether to keep traversing. If the function evaluates to False, traversal is stopped and apply is applied to the current item

delete: lambda: trace, item: str(trace[-1]).startswith("_")

delete allows to drop key/values entirely. Defaults to dropping those keys, which start with _, allowing a commenting-like functionality (especially useful when dealing with jsons).

The fourth parameter is a set of objects implementing the EnumerableHandler interface. Such a handler must be able to iterate through an associated object type and offer some more methods to handle.

decomply

To invoke, the decomply method is used. It's signature is

def decomply(self, item: Union[dict, list], trace: List[Union[str, int]] = None, initial_check: bool = True) -> dict:

It accepts 3 parameters:

item: Union[dict, list]

item is the object to decomply, either a nested dict or list. Both types can appear interchangeably within.

trace: List[Union[str, int]] = None

trace is a list of keys, which are used to traverse the item until a certain place. Typically this trace is initialized as an empty list

initial_check: bool = True

initial_check is a boolean indicating whether the passed item should already be tested against self.traverse.

Complete Example

Let's take the following input

input_data = {
    "First Layer": {
        "Second layer": 3,
        "_Second layer 2nd element": 4,
        "Second layer 3rd element": [
            42,
            69
        ]
    },
    "First layer 2nd element": {
        "fuu": {
            "fuu 1st entry": 6,
            "fuu 2nd entry": 10,
            "fuu 3rd entry": {
                "I will be dropped": 0
            }
        }
    }
}

Decomply(
    traverse = lambda _, item: not isinstance(item, list),
    apply = lambda _, item: item + [666] if isinstance(item, list) else item + 1,
    delete = lambda trace, _: len(trace) > 3
).decomply(input_data)
  • traverse the dict as long as
    • the next item is not a list
    • AND: the item is enumerable (<- this is a mandatory part of the traverse condition always attached within Decomply constructor)
  • When either condition fails, check out the item at hand. If it is
    • a list, extend it with the value 666
    • not a list, increment it by 1
  • Delete all layers with a depth greater than 3

Output

{
    "First Layer": {
        "Second layer": 4,
        "_Second layer 2nd element": 5,
        "Second layer 3rd element": [
            42,
            69,
            666
        ]
    },
    "First layer 2nd element": {
        "fuu": {
            "fuu 1st entry": 7,
            "fuu 2nd entry": 11,
            "fuu 3rd entry": {}
        }
    }
}

I published a use case in my jsgui package, feel free to check it out for more complex examples.

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

decomply-1.1.2.tar.gz (6.1 kB view details)

Uploaded Source

Built Distribution

decomply-1.1.2-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file decomply-1.1.2.tar.gz.

File metadata

  • Download URL: decomply-1.1.2.tar.gz
  • Upload date:
  • Size: 6.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.11.3

File hashes

Hashes for decomply-1.1.2.tar.gz
Algorithm Hash digest
SHA256 c83227e9a3670cc58585db77f1b72d1d898fdbcc8ffc95601303d92508f1a3c6
MD5 f862092963ae1547dde5d8597225c964
BLAKE2b-256 baa35e25b864ec5b6c59277929b7c0eb59f7c5453ecffd21876c87fd26d37c0c

See more details on using hashes here.

File details

Details for the file decomply-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: decomply-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 6.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.11.3

File hashes

Hashes for decomply-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 28f3cf2cdba069351e769a3e5b2bb4245ba4983440d32a3c554879d28718184e
MD5 8044b573d3638e599fb27cfca98e4dcb
BLAKE2b-256 4b04c43ba79db823af95dd7adb0599e7928846e172e7098d2ee57dcfeb8a941b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page