alfred3.util.prefix_keys_safely#

alfred3.util.prefix_keys_safely(data: dict, base: dict, prefix: str = '', sep: str = '_') dict[source]#

Takes the data dict and prefixes its keys in a way that makes sure that there are no keys that are present in both the resulting prefixed dictionary and the base dictionary.

If the planned prefixing of any key in data would result in a conflict with a key in base, the separator sep will be continually repeated until there is no conflict anymore.

For example, a single underscore would be turned into a double underscore on first try. Then into a triple underscore, and so on.

This can be useful, if you want to update the base dictionary with the data dictionary without the danger of losing data.

Returns

A version of the data dictionary, in which all keys received the prefix in a way that does not cause conflicts with the base dictionary.

Return type

dict

Notes

Actually, prefixes of the output dictionary are checked very conservatively, which makes the process more safe and more efficient. The function does not check every single key of the output dictionary, but it checks if any key in the base dictionary has the same prefix. If so, this counts as a key collision and the separator will be repeated.

Examples

In this example, prefixing works without any conflict resolution being necessary:

>>> a = {"k": "val1"}
>>> b = {"k": "val2"}
>>> prefixed = prefix_keys_safely(data=b, base=a, prefix="demo")
>>> prefixed
{"demo_k": "val2"}
>>> a.update(prefixed)
>>> a
{"k": "val1", "demo_k": "val2"}

Second example, demonstrating how conflicts are resolved:

>>> a = {"demo_k": "val1"}
>>> b = {"k": "val2"}
>>> prefixed = prefix_keys_safely(data=b, base=a, prefix="demo")
>>> prefixed
{"demo__k": "val2"}
>>> a.update(prefixed)
>>> a
{"demo_k": "val1", "demo__k": "val2"}

Third example, demonstrating how convervative the approach is. Even though there is no direct collision, the prefix collides with the start of a key in a, which causes the function to repeat the separator:

>>> a = {"demo_key1": "val1"}
>>> b = {"k": "val2"}
>>> prefixed = prefix_keys_safely(data=b, base=a, prefix="demo")
>>> prefixed
{"demo__k": "val2"}
>>> a.update(prefixed)
>>> a
{"demo_key1": "val1", "demo__k": "val2"}