update:要回答我自己的问题,我使用JSON OBJECT_HOOKS做了一个解决方案:
import json
def remove_dots(obj):
for key in obj.keys():
new_key = key.replace(".","-")
if new_key != key:
obj[new_key] = obj[key]
del obj[key]
return obj
output = {'key1': {'key2': 'value2', 'key3': {'key4 with a .': 'value4', 'key5 with a .': 'value5'}}}
new_json = json.loads(json.dumps(output), object_hook=remove_dots)
print new_json
是的,存在更好的方法:
def print_dict(d):
new = {}
for k, v in d.iteritems():
if isinstance(v, dict):
v = print_dict(v)
new[k.replace('.', '-')] = v
return new
defaultdict
等)中得出的类型,也将不仅大约
list
,而且type。
我还在功能开头的最常见类型进行简单类型检查,以减少比较计数(可能会在大量数据中给出一些速度)。为Python 3。替换为py2的工作。
set
如果我了解正确的需求,大多数用户都希望将其与mongoDB一起使用的密钥转换为不允许以关键名称的点。i我使用@HoreJsek的代码,但是我对其进行了调整以接受列表的嵌套字典和替换字符串的函数。 我也有类似的问题要解决:我想在骆驼案例中限制下的小写惯例中替换键,反之亦然。
tuple
there是一个简单的递归解决方案,涉及嵌套列表和字典。
obj.items()
您必须删除原始键,但是您不能在循环的主体中进行操作,因为它会抛出RuntimeRoror:字典在迭代过程中更改了大小。
要解决此问题,通过原始对象的a复制
进行迭代,但要修改原始对象:
obj.iteritems()
def change_keys(obj, convert):
"""
Recursively goes through the dictionary obj and replaces keys with the convert function.
"""
if isinstance(obj, (str, int, float)):
return obj
if isinstance(obj, dict):
new = obj.__class__()
for k, v in obj.items():
new[convert(k)] = change_keys(v, convert)
elif isinstance(obj, (list, set, tuple)):
new = obj.__class__(change_keys(v, convert) for v in obj)
else:
return obj
return new
你可以将所有东西都丢给json 通过整个字符串替换并加载JSON背面
def change_dict_naming_convention(d, convert_function):
"""
Convert a nested dictionary from one convention to another.
Args:
d (dict): dictionary (nested or not) to be converted.
convert_function (func): function that takes the string in one convention and returns it in the other one.
Returns:
Dictionary with the new keys.
"""
new = {}
for k, v in d.iteritems():
new_v = v
if isinstance(v, dict):
new_v = change_dict_naming_convention(v, convert_function)
elif isinstance(v, list):
new_v = list()
for x in v:
new_v.append(change_dict_naming_convention(x, convert_function))
new[convert_function(k)] = new_v
return new
或使用单线
虽然jlopezpino的答案有效,但仅限于词典的开始,这是我的原始变量既要么列表或dict oct。
def change_keys(obj):
new_obj = obj
for k in new_obj:
if hasattr(obj[k], '__getitem__'):
change_keys(obj[k])
if '.' in k:
obj[k.replace('.', '$')] = obj[k]
del obj[k]
there是@Horejsek的回答的1级变体,使用dict理解者对那些喜欢的人:
>>> foo = {'foo': {'bar': {'baz.121': 1}}}
>>> change_keys(foo)
>>> foo
{'foo': {'bar': {'baz$121': 1}}}
我只在Python2.7
def nested_replace(data, old, new):
json_string = json.dumps(data)
replaced = json_string.replace(old, new)
fixed_json = json.loads(replaced)
return fixed_json
动物的方法/解决方案用于更改键:
def short_replace(data, old, new):
return json.loads(json.dumps(data).replace(old, new))
输出:
def fix_camel_cases(data):
def convert(name):
# https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
if isinstance(data, dict):
new_dict = {}
for key, value in data.items():
value = fix_camel_cases(value)
snake_key = convert(key)
new_dict[snake_key] = value
return new_dict
if isinstance(data, list):
new_list = []
for value in data:
new_list.append(fix_camel_cases(value))
return new_list
return data