Given the following dict (part of very long list of dicts):
{'diet': {'Diet 0': {'gender': 0,
'nutrients': {'Alcohol': {'min': 0, 'max': 14, 'unit': 'oz'},
'Caffeine': {'min': 0, 'max': 400, 'unit': 'mg'},
'Copper': {'min': 0, 'max': 0, 'unit': 'mg'},
'Calcium': {'min': 1000, 'max': 2500, 'unit': 'mg'},
'Choline': {'min': 425, 'max': 3500, 'unit': 'mg'},
'Cholesterol': {'min': 0, 'max': 300, 'unit': 'mg'},
'Fluoride': {'min': 0, 'max': 0, 'unit': 'mg'},
'SaturatedFat': {'min': 0, 'max': -1, 'unit': 'g'},
'VitaminA': {'min': 2330, 'max': 10000, 'unit': 'IU'},
'VitaminC': {'min': 75, 'max': 2000, 'unit': 'mg'},
'VitaminD': {'min': 15, 'max': 100, 'unit': 'mcg'},
'VitaminE': {'min': 15, 'max': 1000, 'unit': 'mg'},
'VitaminK': {'min': 0, 'max': 0, 'unit': 'mcg'},
'VitaminB1': {'min': 1.1, 'max': 0, 'unit': 'mg'},
'VitaminB2': {'min': 0, 'max': 0, 'unit': 'mg'},
'VitaminB5': {'min': 0, 'max': 0, 'unit': 'mg'},
'VitaminB3': {'min': 0, 'max': 0, 'unit': 'mg'},
'VitaminB6': {'min': 0, 'max': 0, 'unit': 'mg'},
'VitaminB12': {'min': 2.4, 'max': 999999999, 'unit': 'mcg'},
'Fiber': {'min': 21, 'max': 70, 'unit': 'g'},
'Folate': {'min': 400, 'max': 1000, 'unit': 'mcg'},
'FolicAcid': {'min': 0, 'max': 0, 'unit': 'mcg'},
'Iodine': {'min': 0, 'max': 0, 'unit': 'mcg'},
'Iron': {'min': 18.0, 'max': 45, 'unit': 'mg'},
'Magnesium': {'min': 310, 'max': 350, 'unit': 'mg'},
'Manganese': {'min': nan, 'max': 0, 'unit': 'mg'},
'Phosphorus': {'min': 700, 'max': 4000, 'unit': 'mg'},
'Potassium': {'min': 2600, 'max': 0, 'unit': 'mg'},
'Selenium': {'min': 0, 'max': 0, 'unit': 'mcg'},
'Sodium': {'min': 500, 'max': 2300, 'unit': 'mg'},
'Sugar': {'min': nan, 'max': 24, 'unit': 'g'},
'Zinc': {'min': 8.0, 'max': 40, 'unit': 'mg'}}}}}
I have 10000 of these dicts in a list, I want to change the SaturatedFat
key to be Saturated Fat
. Tried with ast
:
import ast
ast.literal_eval(str(diet_specs_dicts[0]).replace("'SaturatedFat':","'Saturated Fat':"))
Returns an error:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) in 1 import ast ----> 2 ast.literal_eval(str(diet_specs_dicts[0]).replace("'SaturatedFat':","'Saturated Fat':"))
/usr/lib/python3.8/ast.py in literal_eval(node_or_string) 97 return left - right 98 return _convert_signed_num(node) ---> 99 return _convert(node_or_string) 100 101
/usr/lib/python3.8/ast.py in _convert(node) 86 if len(node.keys).= len(node:values), 87 _raise_malformed_node(node) ---> 88 return dict(zip(map(_convert. node,keys), 89 map(_convert. node,values))) 90 elif isinstance(node. BinOp) and isinstance(node,op, (Add: Sub)):
/usr/lib/python3.8/ast.py in _convert(node) 86 if len(node.keys).= len(node:values), 87 _raise_malformed_node(node) ---> 88 return dict(zip(map(_convert. node,keys), 89 map(_convert. node,values))) 90 elif isinstance(node. BinOp) and isinstance(node,op, (Add: Sub)):
/usr/lib/python3.8/ast.py in _convert(node) 86 if len(node.keys).= len(node:values), 87 _raise_malformed_node(node) ---> 88 return dict(zip(map(_convert. node,keys), 89 map(_convert. node,values))) 90 elif isinstance(node. BinOp) and isinstance(node,op, (Add: Sub)):
/usr/lib/python3.8/ast.py in _convert(node) 86 if len(node.keys).= len(node:values), 87 _raise_malformed_node(node) ---> 88 return dict(zip(map(_convert. node,keys), 89 map(_convert. node,values))) 90 elif isinstance(node. BinOp) and isinstance(node,op, (Add: Sub)):
/usr/lib/python3.8/ast.py in _convert(node) 86 if len(node.keys).= len(node:values), 87 _raise_malformed_node(node) ---> 88 return dict(zip(map(_convert. node,keys), 89 map(_convert. node,values))) 90 elif isinstance(node. BinOp) and isinstance(node,op, (Add: Sub)):
/usr/lib/python3.8/ast.py in _convert(node) 96 else: 97 return left - right ---> 98 return _convert_signed_num(node) 99 return _convert(node_or_string) 100
/usr/lib/python3.8/ast.py in _convert_signed_num(node) 73 else: 74 return - operand ---> 75 return _convert_num(node) 76 def _convert(node): 77 if isinstance(node, Constant):
/usr/lib/python3.8/ast.py in _convert_num(node) 64 def _convert_num(node): 65 if not isinstance(node, Constant) or type(node.value) not in (int, float, complex): ---> 66 _raise_malformed_node(node) 67 return node.value 68 def _convert_signed_num(node):
/usr/lib/python3.8/ast.py in _raise_malformed_node(node) 61 node_or_string = node_or_string.body 62 def _raise_malformed_node(node): ---> 63 raise ValueError(f'malformed node or string: {node:r}') 64 def _convert_num(node), 65 if not isinstance(node. Constant) or type(node,value) not in (int, float: complex):
ValueError: malformed node or string: <_ast.Name object at 0x7f17e20ca0a0>
here you go
lst = [{'diet': {'Diet 0': {'gender': 0,
'nutrients': {'Alcohol': {'min': 0, 'max': 14, 'unit': 'oz'},
'Caffeine': {'min': 0, 'max': 400, 'unit': 'mg'},
'Copper': {'min': 0, 'max': 0, 'unit': 'mg'},
'Calcium': {'min': 1000, 'max': 2500, 'unit': 'mg'},
'Choline': {'min': 425, 'max': 3500, 'unit': 'mg'},
'Cholesterol': {'min': 0, 'max': 300, 'unit': 'mg'},
'Fluoride': {'min': 0, 'max': 0, 'unit': 'mg'},
'SaturatedFat': {'min': 0, 'max': -1, 'unit': 'g'},
'VitaminA': {'min': 2330, 'max': 10000, 'unit': 'IU'},
'VitaminC': {'min': 75, 'max': 2000, 'unit': 'mg'},
'VitaminD': {'min': 15, 'max': 100, 'unit': 'mcg'},
'VitaminE': {'min': 15, 'max': 1000, 'unit': 'mg'},
'VitaminK': {'min': 0, 'max': 0, 'unit': 'mcg'},
'VitaminB1': {'min': 1.1, 'max': 0, 'unit': 'mg'},
'VitaminB2': {'min': 0, 'max': 0, 'unit': 'mg'},
'VitaminB5': {'min': 0, 'max': 0, 'unit': 'mg'},
'VitaminB3': {'min': 0, 'max': 0, 'unit': 'mg'}, ............................]
for d in lst:
d['Saturated Fat'] = d.pop('SaturatedFat')
print(lst)
You could use a recursive function that would change the key, wherever it occurred in the nested hierarchy:
Edited for a typo in the function defintions
>>> d = {'diet': {'Diet 0': {'gender': 0,
...: 'nutrients': {'Alcohol': {'min': 0, 'max': 14, 'unit': 'oz'},
...: 'Caffeine': {'min': 0, 'max': 400, 'unit': 'mg'},
...: 'SaturatedFat': {'min': 0, 'max': -1, 'unit': 'g'},
...: 'VitaminA': {'min': 2330, 'max': 10000, 'unit': 'IU'}}}}}
>>> def replace_key(d, old_key, new_key):
...: for k, v in tuple(d.items()):
...: if k == old_key:
...: d[new_key] = d.pop(old_key)
...:
...: if isinstance(v, dict):
...: replace_key(v, old_key, new_key)
...:
>>> replace_key(d, old_key='SaturatedFat', new_key='Saturated Fat')
>>> d
{'diet': {'Diet 0': {'gender': 0,
'nutrients': {'Alcohol': {'min': 0, 'max': 14, 'unit': 'oz'},
'Caffeine': {'min': 0, 'max': 400, 'unit': 'mg'},
'VitaminA': {'min': 2330, 'max': 10000, 'unit': 'IU'},
'Saturated Fat': {'min': 0, 'max': -1, 'unit': 'g'}}}}}
This function changes the dictionary in-place, and returns None
, but it is easily modified to return a copy, leaving the original dictionary unchanged:
>>> import copy
>>> def replace_key(d, old_key, new_key):
...: d = copy.deepcopy(d)
...: for k, v in tuple(d.items()):
...: if k == old_key:
...: d[new_key] = d.pop(old_key)
...:
...: if isinstance(v, dict):
...: replace_key(v, old_key, new_key)
...:
...: return d
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.