flatten icon indicating copy to clipboard operation
flatten copied to clipboard

unflatten(flatten(data)) not the inverse

Open eptx opened this issue 6 years ago • 1 comments

`from flatten_json import flatten from flatten_json import unflatten data = { "a": 1, "b": 2, "c": [{"d": [2, 3, 4], "e": [{"f": 1, "g": 2}]}] }

print(data) flatData = flatten(data) print(flatData) unflat = unflatten(flatData) print(unflat)`

output...

{'a': 1, 'b': 2, 'c': [{'d': [2, 3, 4], 'e': [{'f': 1, 'g': 2}]}]} {'a': 1, 'b': 2, 'c_0_d_0': 2, 'c_0_d_1': 3, 'c_0_d_2': 4, 'c_0_e_0_f': 1, 'c_0_e_0_g': 2} {'a': 1, 'b': 2, 'c': {'0': {'d': {'0': 2, '1': 3, '2': 4}, 'e': {'0': {'f': 1, 'g': 2}}}}}

eptx avatar Mar 20 '18 16:03 eptx

Agreed, I have the same problem. Here is a slightly simpler example.

>>> from pprint import pprint
>>> from flatten_json import flatten, unflatten
>>> x = {'a':['b', 'c']}
>>> pprint(flatten(x))
{'a_0': 'b', 'a_1': 'c'}
>>> pprint(unflatten(flatten(x)))
{'a': {'0': 'b', '1': 'c'}}
>>> 

The problems appears to be that the unflatten does not handle the reconstruction of lists at all.

However, this actually isn't so much of a problem as according to the the README.md, unflatten is not actually supposed to undo flattening.

Calling unflatten_list the dictionary is first unflattened and then in a post-processing step the function looks for a list pattern (zero-indexed consecutive integer keys) and transforms the matched values into a list.

Here's an example:

from flatten_json import unflatten_list
dic = {
   'a': 1,
   'b_0': 1,
   'b_1': 2,
   'c_a': 'a',
   'c_b_0': 1,
   'c_b_1': 2,
   'c_b_2': 3
}
unflatten_list(dic)

returns:

{
   'a': 1,
   'b': [1, 2],
  'c': {'a': 'a', 'b': [1, 2, 3]}
}

So it appears that to fix the issue the code needs to be changed to from flatten_json import unflatten_list as unflatten.

So the correct code would be

>>> from flatten_json import flatten
>>> from flatten_json import unflatten_list as unflatten
>>> data = {
"a": 1,
"b": 2,
"c": [{"d": [2, 3, 4], "e": [{"f": 1, "g": 2}]}]
}
>>> print(data)
{'a': 1, 'b': 2, 'c': [{'d': [2, 3, 4], 'e': [{'f': 1, 'g': 2}]}]}
>>> flatData = flatten(data)
>>> print(flatData)
{'a': 1, 'b': 2, 'c_0_d_0': 2, 'c_0_d_1': 3, 'c_0_d_2': 4, 'c_0_e_0_f': 1, 'c_0_e_0_g': 2}
>>> unflat = unflatten(flatData)
>>> print(unflat)
{'a': 1, 'b': 2, 'c': [{'d': [2, 3, 4], 'e': [{'f': 1, 'g': 2}]}]}

TheMatt2 avatar Apr 02 '18 16:04 TheMatt2