The Dictionary Library.
Project description
:yarn: pydlib
The python dictionary library to get into complex nested python dictionary structures (e.g. json) in a safe and clean way. We take inspiration from Greek myth of Minotaur, where Ariadne with the help of a thread escaped the labyrinth with his beloved Theseus.
Why use pydlib
Sometimes you have to navigate deep json dicts from remote sources, like elastic logs: you can make a series of .get()
and check for None
every time; or you can do obj["path"]["to"]["nested"]["field"]
and wrap everything in a try/except
...
Or you can use pydlib
and write:
pydlib.get(obj, "path.to.nested.field")
to get the value of field
, or None
if anything is not a dict
along the given path.
Installation
To install pydlib, simply use pip
:
$ pip install pydlib
or install from the repository:
$ git clone https://github.com/aitechnologies-it/dlib.git
$ cd dlib
$ python setup.py install
Basic usage
get()
You can get the value from a nested field, just by indicating the path to the nested sub-structure as follows:
>>> import pydlib as dl
>>> dictionary = {
>>> 'path': {
>>> 'to': {
>>> 'nested': {
>>> 'field': 42
>>> }
>>> }
>>> }
>>> }
>>> dl.get(dictionary, path='path.to.nested.field', default=0)
42
Instead, if the field we are looking for doesn't exists, or, if it exists but has a None value, then:
>>> ...
>>> dl.get(dictionary, path='path.to.nested.nonexisting.field', default=0)
0
has()
You can also test for a field simply calling:
>>> import pydlib as dl
>>> dictionary = { ... }
>>> dl.has(dictionary, path='path.to.nested.field')
True
update()
Furthermore, the pydlib comes with built-in functions to also update and delete fields. For example, to update:
>>> import pydlib as dl
>>> dictionary = { ... }
>>> dl.update(dictionary, path='path.to.nested.field', value=1)
{
'path': {
'to': {
'nested': {
'field': 1
}
}
}
}
delete()
Instead, to delete:
>>> import pydlib as dl
>>> dictionary = { ... }
>>> dl.delete(dictionary, path='path.to.nested.field')
{
'path': {
'to': {
'nested': {}
}
}
}
Type-safety
pydlib is type safe, in fact you don't have to manually check the type of inputs, pydlib does it for you:
>>> import pydlib as dl
>>> res = dl.get("not a dictionary", path="nowhere", default=None)
>>> res is None
True
Advanced features
Custom separator
It may happen that a dictionary has a string key with .
in it. In this case you should use a different separator:
>>> import pydlib as dl
>>> d = {"a": {"b.c": 42}}
# Separator conflict
>>> dl.get(d, "a.b.c")
None
# This works!
>>> dl.get(d, "a/b.c", sep="/")
42
Search inside lists
has()
and get()
(but not update
and delete
!) can handle lists. This means that, if a list is encountered, the search for the rest of the path continues for each element of the list. A few examples are needed:
-
b
is a list, get() will return a list with all dictionaries containing the rest of the pathc.d
:>>> d = {"a": {"b": [ {"c": {"d": 1}}, # <-- this {"bad": {"d": 2}}, {"c": {"d": 3}}, # <-- this {"c": {"bad": 4}} ] } } >>> dl.get(d, "a.b.c.d") [1, 3]
-
this works also for nested lists. In this case a nested list of matching depth is returned:
>>> d = {"a": {"b": [ {"c": {"d": [ {"e": 1}, {"e": 2}, {"bad": 3}, ]} }, {"bad": {"d": [ {"e": 4}, ]} }, {"c": {"d": [ {"e": 5}, ]} }, ] } } >>> dl.get(d, "a.b.c.d.e") [[1, 2], [5]]
-
In this case the elements of list
b
are of different types,(1)
and(3)
are dictionaries,(2)
is a list:>>> d = {"a": {"b": [ {"c": {"d": 1}}, # (1) [ {"c": {"d": 3}} ], # (2) {"c": {"d": 4}}, # (3) ] } } >>> dl.get(d, "a.b.c.d") [1, [3], 4]
-
Handling of lists can be disabled by setting
search_lists=False
. Here's different behaviours forsearch_lists
:>>> d = {"a": {"b": [ {"c": {"d": 1}}, {"bad": {"d": 2}}, {"c": {"d": 3}}, {"c": {"bad": 4}} ] } } >>> dl.get(d, "a.b.c.d", search_lists=True) [1, 3] >>> dl.get(d, "a.b.c.d", search_lists=False) None # But if instead we want to get `a.b`, no lists are traversed and both return the value of `b` >>> dl.get(d, "a.b", search_lists=True) [{'c': {'d': 1}}, [{'c': {'d': 3}}], {'c': {'d': 4}}] >>> dl.get(d, "a.b", search_lists=False) [{'c': {'d': 1}}, [{'c': {'d': 3}}], {'c': {'d': 4}}]
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
File details
Details for the file pydlib-0.3.2.tar.gz
.
File metadata
- Download URL: pydlib-0.3.2.tar.gz
- Upload date:
- Size: 4.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.11.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 51e6e9a41aa461952f79451a68d53ab85b75362f3951ec46498407b6c54b779a |
|
MD5 | 7b9b783f22e23aa32b1cc6007c9e088f |
|
BLAKE2b-256 | 153bab4fbb084c28cff308ab806645b20b10012004f044300b8f84cfa62a4c49 |
File details
Details for the file pydlib-0.3.2-py3-none-any.whl
.
File metadata
- Download URL: pydlib-0.3.2-py3-none-any.whl
- Upload date:
- Size: 4.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.11.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3017f508752bdd91690581f9d5548f59b38cff2a146d6e7a378ef0bd447344bc |
|
MD5 | 8089923575b2a7f79fdcae8527f3ad20 |
|
BLAKE2b-256 | b916d6c5b8dfa9a95af40dde645d1136c4203c75ef4626ab5059d88acd309b8e |