flatdict icon indicating copy to clipboard operation
flatdict copied to clipboard

Add `guess_lists` option when unflattening FlatterDict

Open whophil opened this issue 3 years ago • 6 comments

Add a guess_lists option to FlatterDict.as_dict() which, when unflattening a FlatterDict containing no information about original_types, attempts to guess which of its sub-dicts should actually be lists.

Addresses #49

A sub-dict is guessed to be a list if:

  • all of its keys are strings
  • all of its keys can be converted to integers
  • the keys represent a contiguous sequence of integers starting at 0, e.g., [0, 1, 2, 3, ..., n]

This is only a heuristic, as a dict may actually have keys satisfying the above criteria.

whophil avatar Jun 18 '22 15:06 whophil

Thanks @gmr for your work on this project! This PR is ready for review.

whophil avatar Jun 21 '22 14:06 whophil

Bump @gmr - sorry for the squeaky wheel treatment here.

I know it's only been a week or so, but is this a project you still have time/interest in maintaining?

Thanks again!

whophil avatar Jun 28 '22 18:06 whophil

One more bump! @gmr

whophil avatar Jul 15 '22 19:07 whophil

I don't understand the use case of the MR.

It looks to me like you want the .values() of a dict in certain cases, and not others?

Is the goal to turn:

foo:bar:baz:0 = 'a'
foo:bar:baz:1 = 'b'
foo.bar.baz:2 = 'c'

into:

foo:bar:baz = ['a','b','c']

gmr avatar Jul 19 '22 14:07 gmr

Hi @gmr , that is indeed the desired behavior. This is further described in https://github.com/gmr/flatdict/issues/49, but not sure if that's any more clear.

Here is a complete snippet

import flatdict

d = {}
d['foo:bar:baz:0'] = 'a'
d['foo:bar:baz:1'] = 'b'
d['foo:bar:baz:2'] = 'c'

print(flatdict.FlatterDict(d).as_dict(guess_lists=False))
print(flatdict.FlatterDict(d).as_dict(guess_lists=True))

which outputs

{'foo': {'bar': {'baz': {'0': 'a', '1': 'b', '2': 'c'}}}}
{'foo': {'bar': {'baz': ['a', 'b', 'c']}}}

Setting guess_lists=False makes FlatterDict.as_dict() act the same as it currently does on the master branch. As you can see, values which are list-like in the FlatterDict do not come back list-like after "unflattening." With guess_lists=True, they do.

The use case: Serialize a "flatter" dictionary to JSON and deserialize it elsewhere.

whophil avatar Jul 19 '22 14:07 whophil

This PR is a great addition in my view and I have pulled this branch down and used in my project as this parsing into lists is exactly what was missing from flatdict.FlatterDict.

Are updates being added to this package? It seems not. Shame as flattening and unflattening dictionaries is a core capability needed in my use cases. I would consider accepting the PRs and submitting to a new pipy namespace.

ttamg avatar Feb 14 '23 07:02 ttamg