0

I have a nested dictionary and I want to replace a particular key. when I try to replace the key using replace, I get an error.

a = {'Stefan':  [('__label__A', 0.90), ('__label__O', 0.06), ('__label__I', 0.01)],
     'William': [('__label__A', 0.73), ('__label__B', 0.12), ('__label__U', 0.06)],
     'James':   [('__label__A', 0.63), ('__label__O', 0.35), ('__label__U', 0.01)]
    }

_names = list(a.keys())
# for i in range(len(3)
tmp = a.get(_names[0])[0][0]
if tmp == '__label__W':
    tmp = 'White'
elif tmp == '__label__A':
    tmp = 'Asian'
elif tmp == '__label__B':
    tmp = 'Black'
elif tmp == '__label__I':
    tmp = 'Alaskan'
elif tmp == '__label__O':
    tmp = 'other'
elif tmp == '__label__M':
    tmp = 'Two races'
else:
    tmp = 'Undesginated'
a.replace(a.get(_names[0])[0][0],tmp)
#(a.keys()).replace('__label__A','Asian')
#(a.get(_names[0])[0][0]).replace(tmp)
#a.replace('__label__A','Asian')
print(a)

I get error:

AttributeError: 'dict' object has no attribute 'replace'

The labels should be replaced as such

{'__label__W':'White', '__label__A': 'Asian', 
 '__label__B': 'Black','__label__I': 'Alaskan', 
 '__label__O': 'other','__label__M': 'Two races',
 '__label__U': 'Undesginated'}

How to use replace command in this case or is there any better way ?

Joe Iddon
  • 20,101
  • 7
  • 33
  • 54
Raady
  • 1,686
  • 5
  • 22
  • 46
  • 1
    You cant replace dict keys like that, have a look at : https://stackoverflow.com/questions/4406501/change-the-name-of-a-key-in-dictionary – Rohi Apr 22 '18 at 13:00
  • 1
    @Rohi They're actually trying to replace the first element in a tuple. I think. – Aran-Fey Apr 22 '18 at 13:01
  • I'm not 100% sure what your expected result would be. Can you show us what the dict should look like after the substitution? – Aran-Fey Apr 22 '18 at 13:02

2 Answers2

1

Tuples are immutable, so you can't replace or reassign their values. However, you can replace the whole tuple in the surrounding lists.

To make this easier than using a big for-loop and lots of if-statements, we should define a replacement dictionary so it is easier to modify things and add/remove entries in the future.

replacements = {'__label__W': 'White', '__label__A': 'Asian', 
                '__label__B': 'Black', '__label__I': 'Alaskan', 
                '__label__O': 'other', '__label__M': 'Two races',
                '__label__U': 'Undesginated'}

Now we could use a for-loop to loop over the keys in the a dictionary as you have done, but personally I would find it easier to just re-define the whole dictionary with a comprehension.

You may not be used to dictionary-comprehensions, but they are fairly self-explanatory:

{n:[(replacements[i], j) for i, j in l] for n, l in a.items()}

which gives:

{'Stefan':  [('Asian', 0.9),  ('other', 0.06), ('Alaskan',      0.01)], 
 'William': [('Asian', 0.73), ('Black', 0.12), ('Undesginated', 0.06)],
 'James':   [('Asian', 0.63), ('other', 0.35), ('Undesginated', 0.01)]}

To replace just one, you would have to redefine the whole tuple:

a['Stefan'][0] = ('Asian', a['Stefan'][0][1])

giving:

{'Stefan':  [('Asian',      0.9),  ('__label__O', 0.06), ('__label__I', 0.01)],
 'William': [('__label__A', 0.73), ('__label__B', 0.12), ('__label__U', 0.06)],
 'James':   [('__label__A', 0.63), ('__label__O', 0.35), ('__label__U', 0.01)]}
Joe Iddon
  • 20,101
  • 7
  • 33
  • 54
0

Try this instead of a.replace(a.get(_names[0])[0][0],tmp)

a[_names[0]][0]=(tmp, a[_names[0]][0][1])

>a[_names[0]][0]
('Asian', 0.73)
Mehrdad Pedramfar
  • 10,941
  • 4
  • 38
  • 59