2

This question is connected to [-> here].
I would like to reorganize the following nested dict please:

a = {
 (0.0, 0.0): {'a': [25, 29, nan]},
 (0.0, 2.0): {'a': [25, 29, nan], 'b': [25, 35, 31.0]},
 (0.0, 4.0): {'b': [25, 35, 31.0]},
 (2.0, 0.0): {'a': [25, 29, nan], 'c': [25, 26, 29.0]},
 (2.0, 1.5): {'a': [25, 29, nan], 'c': [25, 26, 29.0]},
 (2.0, 2.0): {'a': [25, 29, nan], 'b': [25, 35, 31.0]},
 (2.0, 4.0): {'b': [25, 35, 31.0]},
 (3.0, 3.0): {'d': [25, 31, 32.0]},
 (3.0, 5.0): {'d': [25, 31, 32.0]},
 (5.0, 0.0): {'c': [25, 26, 29.0]},
 (5.0, 1.5): {'c': [25, 26, 29.0]},
 (5.0, 3.0): {'d': [25, 31, 32.0]},
 (5.0, 5.0): {'d': [25, 31, 32.0]},
 (6.0, 1.0): {'e': [25, 28, 30.0]},
 (6.0, 3.0): {'e': [25, 28, 30.0]},
 (8.0, 1.0): {'e': [25, 28, 30.0]},
 (8.0, 3.0): {'e': [25, 28, 30.0]}
}

I want to swap the inner and outer keys.
Some outer keys will duplicate and the value should become a list of lists. The result should be:

{'a': {(0.0, 0.0): [[25, 29, nan]],
       (0.0, 2.0): [[25, 29, nan], [25, 35, 31.0]],
       (2.0, 0.0): [[25, 29, nan], [25, 26, 29.0]],
       (2.0, 1.5): [[25, 29, nan], [25, 26, 29.0]],
       (2.0, 2.0): [[25, 29, nan], [25, 35, 31.0]]},
 'b': {(0.0, 2.0): [[25, 29, nan], [25, 35, 31.0]],
       (0.0, 4.0): [[25, 35, 31.0]],
       (2.0, 2.0): [[25, 29, nan], [25, 35, 31.0]],
       (2.0, 4.0): [[25, 35, 31.0]]},
 'c': {(2.0, 0.0): [[25, 29, nan], [25, 26, 29.0]],
       (2.0, 1.5): [[25, 29, nan], [25, 26, 29.0]],
       (5.0, 0.0): [[25, 26, 29.0]],
       (5.0, 1.5): [[25, 26, 29.0]]},
 'd': {(3.0, 3.0): [[25, 31, 32.0]],
       (3.0, 5.0): [[25, 31, 32.0]],
       (5.0, 3.0): [[25, 31, 32.0]],
       (5.0, 5.0): [[25, 31, 32.0]]},
 'e': {(6.0, 1.0): [[25, 28, 30.0]],
       (6.0, 3.0): [[25, 28, 30.0]],
       (8.0, 1.0): [[25, 28, 30.0]],
       (8.0, 3.0): [[25, 28, 30.0]]}
}

Intuition tells me pd.DataFrame with a .groupby() [and cull the NaN cells] would be the way to go...

df = pd.DataFrame(dict_vertices)
print(df.head(2))
             0.0               2.0                    ...  8.0       6.0
             0.0               0.0               1.5  ...  1.0  3.0  3.0
a  [25, 29, nan]     [25, 29, nan]     [25, 29, nan]  ...  NaN  NaN  NaN
c            NaN  [[25, 26, 29.0]]  [[25, 26, 29.0]]  ...  NaN  NaN  NaN

[2 rows x 17 columns]

...but I don't know.
How do I reorganize the following nested dict please; where the value follows the outer key?

arkriger
  • 207
  • 2
  • 7
  • Where does `[25, 26, 29.0]` come from in `result['a'][(2.0, 0.0)]`? There's nothing like that in `a[(2.0, 0.0)]['a']` – Barmar Jun 01 '23 at 17:01
  • I see that in `a[(2.0, 0.0)]['c']` but why should that be copied to the `a` key of the result? – Barmar Jun 01 '23 at 17:03
  • Why are some of the values in the original dict lists, and others are list of list? – Barmar Jun 01 '23 at 17:03
  • Your desired result has more lists than the input does. Where are these coming from? – Barmar Jun 01 '23 at 17:08

1 Answers1

1

You can use:

out = {}

for k1, d in a.items():
    for k2 in d:
        out.setdefault(k2, {})[k1] = list(d.values())

Output:

{'a': {(0.0, 0.0): [[25, 29, nan]],
       (0.0, 2.0): [[25, 29, nan], [[25, 35, 31.0]]],
       (2.0, 0.0): [[25, 29, nan], [[25, 26, 29.0]]],
       (2.0, 1.5): [[25, 29, nan], [[25, 26, 29.0]]],
       (2.0, 2.0): [[25, 29, nan], [[25, 35, 31.0]]]},
 'b': {(0.0, 2.0): [[25, 29, nan], [[25, 35, 31.0]]],
       (0.0, 4.0): [[25, 35, 31.0]],
       (2.0, 2.0): [[25, 29, nan], [[25, 35, 31.0]]],
       (2.0, 4.0): [[25, 35, 31.0]]},
 'c': {(2.0, 0.0): [[25, 29, nan], [[25, 26, 29.0]]],
       (2.0, 1.5): [[25, 29, nan], [[25, 26, 29.0]]],
       (5.0, 0.0): [[25, 26, 29.0]],
       (5.0, 1.5): [[25, 26, 29.0]]},
 'd': {(3.0, 3.0): [[25, 31, 32.0]],
       (3.0, 5.0): [[25, 31, 32.0]], 
       (5.0, 3.0): [[25, 31, 32.0]],
       (5.0, 5.0): [[25, 31, 32.0]]},
 'e': {(6.0, 1.0): [[25, 28, 30.0]],
       (6.0, 3.0): [[25, 28, 30.0]],
       (8.0, 1.0): [[25, 28, 30.0]],
       (8.0, 3.0): [[25, 28, 30.0]]},
}
mozway
  • 194,879
  • 13
  • 39
  • 75
  • Thank you @mozway. Can you tell me why: `result.setdefault(k2, {})[k1] = list(dict.fromkeys([j for i in d.values() for j in i]))` does not merge and sort the **lists of values** into one ascending `list` please? – arkriger Jun 02 '23 at 16:46
  • @arkriger what exactly do you mean by "*one ascending list*" and why would you expect this behavior? – mozway Jun 02 '23 at 17:23
  • You are very considerate @mozway; thank you. I would like the **value** as one sorted list and had hoped that changing that last line to: `out.setdefault(k2, {})[k1] = list(dict.fromkeys([j for i in d.values() for j in i]))` would achieve it. It does not sort the list. How do I sort the list please? – arkriger Jun 02 '23 at 20:37
  • I see, if your goal is to obtain a single flat list you have to unnest the initial nested list. If the nesting is arbitrary you might need to use a recursive function. – mozway Jun 03 '23 at 03:40
  • it was `sorted` and `set`. `result.setdefault(k2, {})[k1] = sorted(list(set([j for i in d.values() for j in i])))` did the business @mozway. Thank you. – arkriger Jun 03 '23 at 13:06