简体   繁体   中英

Modify dictionary key

Hi I have a dictionary like below

{
'namelist': [{'name':"John",'age':23,'country':'USA'},
                   {'name':"Mary",'age':12,'country':'Italy'},
                   {'name':"Susan",'age':32,'country':'UK'}],
'classteacher':'Jon Smith'
}

I would like to know is it possible to change it to

 {
 'namelist': [{'name_1':"John",'age_1':23,'country_1':'USA'},
               {'name_2':"Mary",'age_2':12,'country_3':'Italy'},
               {'name_3':"Susan",'age_3':32,'country_3':'UK'}],
 'classteacher':'Jon Smith'
 }

By adding _1, _2 .... on every last position of every key Is it possible? Thank you for your help

You can add the new values in the initial list with changing the key and removing the initial values yourdict[j+'_'+str(num)] = yourdict.pop(j)

keys() returns all the keys of a dict ( name, age, country in your case)

a = {'namelist': [{'name':"John",'age':23,'country':'USA'},
                  {'name':"Mary",'age':12,'country':'Italy'},
                  {'name':"Susan",'age':32,'country':'UK'}]}

num = 1
for i in a['namelist']:
    for j in list(i.keys()):
        i[j+'_'+str(num)] = i.pop(j)
    num += 1

print(a)
# {'namelist': [
#    {'name_1': 'John', 'country_1': 'USA', 'age_1': 23}, 
#    {'name_2': 'Mary', 'country_2': 'Italy', 'age_2': 12}, 
#    {'name_3': 'Susan', 'age_3': 32, 'country_3': 'UK'}]}

Using enumerate

Ex:

d = {'namelist': [{'name':"John",'age':23,'country':'USA'},
               {'name':"Mary",'age':12,'country':'Italy'},
               {'name':"Susan",'age':32,'country':'UK'}]}

d["namelist"] = [{k+"_"+str(i): v for k,v in value.items()} for i , value in enumerate(d["namelist"], 1)]
print(d)  

Output:

{'namelist': [{'age_1': 23, 'country_1': 'USA', 'name_1': 'John'},
              {'age_2': 12, 'country_2': 'Italy', 'name_2': 'Mary'},
              {'age_3': 32, 'country_3': 'UK', 'name_3': 'Susan'}]}

You will have to create new key, with value correspond to old key. You can achieve this easily in one line using dict.pop

I will assume you want to add index of the row into field name . For other fields or modified them in other ways, you can do similarly.

for index, row in enumerate(a['namelist']):
    row['name_%d' % index] = row.pop('name')

Output:

{'namelist': [{'age': 23, 'country': 'USA', 'name_0': 'John'},
  {'age': 12, 'country': 'Italy', 'name_1': 'Mary'},
  {'age': 32, 'country': 'UK', 'name_2': 'Susan'}]}

Here is my one-line style solution, which works even if you have many keys other than 'namelist':

d = {'namelist': [{'name':"John",'age':23,'country':'USA'},
                   {'name':"Mary",'age':12,'country':'Italy'},
                   {'name':"Susan",'age':32,'country':'UK'}],
     'classteacher':'Jon Smith'
    }


d = {k:[{f'{k2}_{nb}':v2 for k2,v2 in i.items()} for nb,i in enumerate(v,1)] if isinstance(v,list) else v for k,v in d.items()}

print(d)
# {'namelist': [{'name_1': 'John', 'age_1': 23, 'country_1': 'USA'},
#               {'name_2': 'Mary', 'age_2': 12, 'country_2': 'Italy'},
#               {'name_3': 'Susan', 'age_3': 32, 'country_3': 'UK'}]}, 
#  'classteacher': 'Jon Smith'
# }

However as Aran-Fey said, this is not really readable and very difficult to maintain. So I also suggest you the solution with nested for loops:

d1 = {'namelist': [{'name':"John",'age':23,'country':'USA'},
                   {'name':"Mary",'age':12,'country':'Italy'},
                   {'name':"Susan",'age':32,'country':'UK'}],
      'classteacher':'Jon Smith'}

for k1,v1 in d1.items():
    if isinstance(v1,list):
        for nb,d2 in enumerate(v1,1):
            for k2 in list(d2):
                d2[f'{k2}_{nb}'] = d2.pop(k2)

print(d1)
# {'namelist': [{'name_1': 'John', 'age_1': 23, 'country_1': 'USA'},
#               {'name_2': 'Mary', 'age_2': 12, 'country_2': 'Italy'},
#               {'name_3': 'Susan', 'age_3': 32, 'country_3': 'UK'}]}, 
#  'classteacher': 'Jon Smith'
# }

You can use dict and list comprehensions:

d = {'namelist': [{'name': "John", 'age': 23, 'country': 'USA'},
              {'name': "Mary", 'age': 12, 'country': 'Italy'},
              {'name': "Susan", 'age': 32, 'country': 'UK'}]}
d = {k: [{'_'.join((n, str(i))): v for n, v in s.items()} for i, s in enumerate(l, 1)] for k, l in d.items()}

d would become:

{'namelist': [{'name_1': 'John', 'age_1': 23, 'country_1': 'USA'}, {'name_2': 'Mary', 'age_2': 12, 'country_2': 'Italy'}, {'name_3': 'Susan', 'age_3': 32, 'country_3': 'UK'}]}
for i, dct in enumerate(inp['namelist'], 1):
    for key, value in list(dct.items()):  # take a copy since we are modifying the dct
        del dct[key]  # delete old pair
        dct[key+'_'+str(i)] = value  # new key format

This would be in place. You are not using extra memory. Iterating over each value inside the dict and then deleting the old key-value pair and adding the it with a change in the key name.

使用字典理解:

    mydictionary['namelist'] = [dict((key + '_' + str(i), value) for key,value in mydictionary['namelist'][i-1].items()) for i in [1, 2, 3]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM