benwagner
benwagner

Reputation: 25

Reversing dictionary with key and values as sublist

I wanted to see if anybody can come up with an idea to solve a problem I came across.

I want to try to somehow flip the sublist and lists of a dictionary. The following should present what I am aiming to do.

olddict = {
  'Cat1': {
    'a': 0.9628883469409395,
    'b': 0.2215033887861984,
    'c': 0.011300919842312747,
    'd': 0.006507874528179097,
    'e': 0.0038535645472061657},
  'Cat2': {'a': 0.9984095005831831,
    'b': 0.7831176833025262,
    'c': 0.2980289093298292,
    'd': 0.04152023948978264,
    'e': 0.9772639691714836},
  'Cat3': {'a': 0.467005076142132,
    'b': 1.0,
    'c': 0.9810315430520035,
    'd': 0.37869041728517233,
    'e': 0.5812393632996296}}

into something like this:

newdict = {
  'a': {
    'Cat1': 0.9628883469409395,
    'Cat2': 0.9984095005831831,
    'Cat3': 0.467005076142132},
  'b': {
    'Cat1': 0.2215033887861984,
    'Cat2': 0.7831176833025262,
    'Cat3': 1.0},
  'c': {
    'Cat1': 0.011300919842312747,
    'Cat2': 0.2980289093298292,
    'Cat3': 0.9810315430520035},
  'd': {
    'Cat1': 0.9628883469409395,
    'Cat2': 0.04152023948978264,
    'Cat3': 0.37869041728517233},
  'e': {
    'Cat1': 0.0038535645472061657,
    'Cat2': 0.9772639691714836,
    'Cat3': 0.5812393632996296}}

With this I am able to create the general layout of the new dictionary. However, I am failing in also adding the values.

newdict = {}
for key, value in olddict.items():
    for string,v in value.items():
        newdict.setdefault(string, []).append(key)

I would appreciate any help. Thanks so much in advance!

Upvotes: 2

Views: 53

Answers (4)

javidcf
javidcf

Reputation: 59711

Your solution with setdefault is almost correct, but you are using dicts, not lists, so you should do:

olddict = {'Cat1': {'a': 0.9628883469409395,
  'b': 0.2215033887861984,
  'c': 0.011300919842312747,
  'd': 0.006507874528179097,
  'e': 0.0038535645472061657},
'Cat2': {'a': 0.9984095005831831,
  'b': 0.7831176833025262,
  'c': 0.2980289093298292,
  'd': 0.04152023948978264,
  'e': 0.9772639691714836},
'Cat3': {'a': 0.467005076142132,
  'b': 1.0,
  'c': 0.9810315430520035,
  'd': 0.37869041728517233,
  'e': 0.5812393632996296}}

expected = {'a': {'Cat1': 0.9628883469409395,
  'Cat2': 0.9984095005831831,
  'Cat3': 0.467005076142132},
'b': {'Cat1': 0.2215033887861984,
  'Cat2': 0.7831176833025262,
  'Cat3': 1.0},
'c': {'Cat1': 0.011300919842312747,
  'Cat2': 0.2980289093298292,
  'Cat3': 0.9810315430520035},
'd': {'Cat1': 0.006507874528179097,
  'Cat2': 0.04152023948978264,
  'Cat3': 0.37869041728517233},
'e': {'Cat1': 0.0038535645472061657,
  'Cat2': 0.9772639691714836,
  'Cat3': 0.5812393632996296}}

newdict = {}
for key, value in olddict.items():
    for s, v in value.items():
        newdict.setdefault(s, {})[key] = v
print(newdict == expected)
# True

Upvotes: 0

ComplicatedPhenomenon
ComplicatedPhenomenon

Reputation: 4189

import pandas as pd 
olddict = {'Cat1': {'a': 0.9628883469409395,
  'b': 0.2215033887861984,
  'c': 0.011300919842312747,
  'd': 0.006507874528179097,
  'e': 0.0038535645472061657},
'Cat2': {'a': 0.9984095005831831,
  'b': 0.7831176833025262,
  'c': 0.2980289093298292,
  'd': 0.04152023948978264,
  'e': 0.9772639691714836},
'Cat3': {'a': 0.467005076142132,
  'b': 1.0,
  'c': 0.9810315430520035,
  'd': 0.37869041728517233,
  'e': 0.5812393632996296}} 
df=pd.DataFrame(olddict)
df = df.T 
df.to_dict() 

Output:

{'a': {'Cat1': 0.9628883469409395,
  'Cat2': 0.9984095005831831,
  'Cat3': 0.467005076142132},
 'b': {'Cat1': 0.2215033887861984, 'Cat2': 0.7831176833025262, 'Cat3': 1.0},
 'c': {'Cat1': 0.011300919842312747,
  'Cat2': 0.2980289093298292,
  'Cat3': 0.9810315430520035},
 'd': {'Cat1': 0.006507874528179097,
  'Cat2': 0.04152023948978264,
  'Cat3': 0.37869041728517233},
 'e': {'Cat1': 0.0038535645472061657,
  'Cat2': 0.9772639691714836,
  'Cat3': 0.5812393632996296}}

Upvotes: 1

Michael Bianconi
Michael Bianconi

Reputation: 5242

newdict = defaultdict(dict)
for cat, letters in olddict.items():
  for letter, value in letters.items():
    newdict[letter][cat] = value

Upvotes: 3

chris
chris

Reputation: 2063

Try using a defaultdict. They're magical.

https://docs.python.org/3/library/collections.html#collections.defaultdict

>>> from collections import defaultdict
>>> from pprint import pprint
>>>
>>> newdict = defaultdict(dict)
>>> for key, value in olddict.items():
...     for string, v in value.items():
...             newdict[string][key] = v
>>>
>>> pprint(newdict)
defaultdict(<class 'dict'>,
            {'a': {'Cat1': 0.9628883469409395,
                   'Cat2': 0.9984095005831831,
                   'Cat3': 0.467005076142132},
             'b': {'Cat1': 0.2215033887861984,
                   'Cat2': 0.7831176833025262,
                   'Cat3': 1.0},
             'c': {'Cat1': 0.011300919842312747,
                   'Cat2': 0.2980289093298292,
                   'Cat3': 0.9810315430520035},
             'd': {'Cat1': 0.006507874528179097,
                   'Cat2': 0.04152023948978264,
                   'Cat3': 0.37869041728517233},
             'e': {'Cat1': 0.0038535645472061657,
                   'Cat2': 0.9772639691714836,
                   'Cat3': 0.5812393632996296}})

Upvotes: 2

Related Questions