Python 根据值的键修改嵌套字典中的值
我有以下字典:Python 根据值的键修改嵌套字典中的值,python,dictionary,Python,Dictionary,我有以下字典: input_processed = {'units' : {'g' : 'g', 'dx' : 'cm', 'po' : 'bar', 'muo' : 'mPas'}, 'g' : 1.0, 'dx' : [10.0, 20.0
input_processed = {'units' : {'g' : 'g',
'dx' : 'cm',
'po' : 'bar',
'muo' : 'mPas'},
'g' : 1.0,
'dx' : [10.0, 20.0, 10.0],
'muo' : {'po' : [0.0, 1.0],
'muo' : [32.7, 32.7]},
'phi' : 0.05}
commands_variables = {'units' : [],
'g' : ['g'],
'dx' : ['dx'],
'muo' : ['po', 'muo'],
'phi' : ['phi']}
conversion_factors = {'g' : 9.81,
'cm' : 0.01,
'bar' : 10**5,
'mPas' : 10**-3}
我的目标是将input\u processed
中的每个浮点乘以conversion\u factors
中为某些变量定义的因子。由于命令(处理的input\u中的最高级别键
可以定义多个变量,因此这些变量映射到commands\u variables
中
所以首先我需要检查变量是否包含在input\u processed['units]中
,因为phi
没有单位。然后对于每个命令中的每个变量,我需要获得单位。在下一步中,我根据单位从转换系数中获得转换系数。由于输入处理的最高级别键的值可以是float、list或dict类型,我编写了一个不同的方法。它被放入一个函数中,并在处理的输入上的循环中调用
def convert_unit(data, command, parameter):
for it in commands_variables[command]:
if it in data['units']:
variable = it
else:
continue
unit = data['units'][variable]
conversion_factor = conversion_factors[unit]
if type(parameter) is float:
converted = parameter*conversion_factor
elif type(parameter) is list:
converted = [parameter[it]*conversion_factor
for it in range(len(parameter))]
elif type(parameter) is OrderedDict:
for key, value in parameter.items():
value = parameter[key]
converted = [value[it]*conversion_factor
for it in range(len(value))]
return converted
input_converted = {}
for key, value in input_processed.items():
input_converted[key] = convert_unit(input_processed, key, value)
所需的输出用于该功能
9.81
[0.1, 0.2, 0.1]
{'po' : [0.0, 100000.0], 'muo' : [0.0327, 0.0327]}
0.05
主节目呢
input_processed = {'units' : {'g' : 'g',
'dx' : 'cm',
'po' : 'bar',
'muo' : 'mPas'},
'g' : 9.81,
'dx' : [0.1, 0.2, 0.1],
'muo' : {'po' : [0.0, 100000.0],
'muo' : [0.0327, 0.0327]},
'phi' : 0.05}
我成功地转换了浮点和列表,但没有转换字典。在这个简短的问题陈述中,我有一个错误,即在赋值之前引用了局部变量“converted”
如果有人有一种更简单的方法来转换数量,我将不胜感激。现有代码的主要问题是
for key, value in parameter.items():
循环不会累积嵌套字典中已更改的项,因此由该部分代码生成的转换后的项将仅是参数中最后转换的项;而且该部分仅处理列表中的嵌套字典项,在普通浮动时将失败
FWIW,在主for
循环底部的return converted
看起来有点可疑:循环内的无条件return
将导致函数在第一次循环迭代结束时返回。这实际上是可以的,因为我们确实希望在数据中成功匹配后退出循环['units']
,但对于阅读您的代码的人来说,这仍然有点棘手
一个小问题是使用type
进行类型测试。建议改为使用。有关详细信息,请参阅。正如那里的答案所述,最好尽可能避免在Python中签入type
,因为这会干扰duck类型
无论如何,这里是您的函数的一个修改版本。我的代码在Python 2.6.6上进行了测试,但它应该在Python 3上正确执行……我想。:)
输出
{'dx': [0.10000000000000001, 0.20000000000000001, 0.10000000000000001],
'g': 9.8100000000000005,
'muo': {'muo': [0.032700000000000007, 0.032700000000000007],
'po': [0.0, 100000.0]},
'phi': 0.050000000000000003,
'units': {'dx': 'cm', 'g': 'g', 'muo': 'mPas', 'po': 'bar'}}
FWIW,虽然pprint.pprint
可以显示字典,但是使用json.dumps
可以获得更漂亮的输出现有代码的主要问题是
for key, value in parameter.items():
循环不会累积嵌套字典中已更改的项,因此由该部分代码生成的转换后的项将仅是参数中最后转换的项;而且该部分仅处理列表中的嵌套字典项,在普通浮动时将失败
FWIW,在主for
循环底部的return converted
看起来有点可疑:循环内的无条件return
将导致函数在第一次循环迭代结束时返回。这实际上是可以的,因为我们确实希望在数据中成功匹配后退出循环['units']
,但对于阅读您的代码的人来说,这仍然有点棘手
一个小问题是使用type
进行类型测试。建议改为使用。有关详细信息,请参阅。正如那里的答案所述,最好尽可能避免在Python中签入type
,因为这会干扰duck类型
无论如何,这里是您的函数的一个修改版本。我的代码在Python 2.6.6上进行了测试,但它应该在Python 3上正确执行……我想。:)
输出
{'dx': [0.10000000000000001, 0.20000000000000001, 0.10000000000000001],
'g': 9.8100000000000005,
'muo': {'muo': [0.032700000000000007, 0.032700000000000007],
'po': [0.0, 100000.0]},
'phi': 0.050000000000000003,
'units': {'dx': 'cm', 'g': 'g', 'muo': 'mPas', 'po': 'bar'}}
FWIW,虽然pprint.pprint
可以显示字典,但使用json可以获得更漂亮的输出。转储
如果输入数据的结构更简单,则会更容易。使用dict
而不是y中的OrderedDict
可以解决“分配前引用”错误的问题我们的代码。如果您的输入数据具有更简单的结构,则会更容易。使用dict
而不是代码中的OrderedDict
可以解决“分配前引用”错误的问题。非常感谢:)这在Python 3.5.1中运行良好。@jseelig:很高兴!感谢您的反馈:Python 3.5。1.非常感谢:)这在Python3.5.1中运行得很好。@jseelig:我的荣幸!感谢您对Python3.5.1的反馈。