提问人:Soma Juice 提问时间:11/17/2023 最后编辑:Soma Juice 更新时间:11/17/2023 访问量:48
更新字典嵌套数组中的字典
update dictionary in nested array of dictionaries
问:
我想根据 opti 数组中的值更新 list2,以便它检查嵌套数组是否具有键为“RSI_15”的字典,然后使用同一数组中的键“val”更新字典,依此类推 opti 数组中的所有数组。
现在我的输出是这样的
[['random', {'ind': 'RSI_15'}, {'cond': '<'}, {'val': 1000}], ['random', {'ind': 'volume'}, {'cond': '>'}, {'val': 1000}]]
很明显,我的 for 循环覆盖了它,但我无法破解逻辑
我希望的输出是这样的:
[['random', {'ind': 'RSI_15'}, {'cond': '<'}, {'val': 15}], ['random', {'ind': 'volume'}, {'cond': '>'}, {'val': 1000}]]
法典:
list2 = [['random', {'ind': 'RSI_15'}, {'cond': '<'}, {'val': 12}], ['random', {'ind': 'volume'}, {'cond':
'>'}, {'val': 44}]]
opti = [['RSI_15', 15], ['volume', 1000]]
def update_val(indicator, val, values):
flag = False
for v in values:
if isinstance(v, dict) and flag == False:
try:
v['ind'] = indicator
flag = True
except:
continue
if isinstance(v, dict) and flag == True:
try:
if v['val'] :
v['val'] = val
flag = True
except:
continue
def up(conds, opti_val):
for cond in conds:
for item in opti_val:
update_val(item[0], item[1], cond)
return conds
list2 = up(list2, opti)
print(list2)
答:
1赞
Barmar
11/17/2023
#1
我无法弄清楚你的逻辑应该如何工作,因为你在条件语句之外进行了比较。v['ind'] == indicator
但是,使用搜索列表的函数可以大大简化它,而不是使用令人困惑的变量进行循环。any()
flag
def update_val(indicator, val, values):
if any(isinstance(v, dict) and v.get('ind') == indicator for v in values):
for v in values:
if isinstance(v, dict) and 'val' in v:
v['val'] = val;
break
评论
0赞
Soma Juice
11/17/2023
噢:D噢非常感谢伙计!
0赞
Barmar
11/17/2023
是的,这是一个非常有用的功能。
0赞
Barmar
11/17/2023
您还应该考虑重新设计数据结构。列表通常应具有统一的数据,并且每个字典具有不同键的字典列表是反模式。为什么列表不像字典?{'type': 'random', 'ind': 'RSI_15', 'cond': <', 'val': 15}
0赞
Soma Juice
11/17/2023
是的,这是一个很好的观点,但恐怕必须是这种抽搐的方式
1赞
alec_djinn
11/17/2023
#2
你的方法过于复杂。您可以使用对特定数据结构进行操作的单个函数来完成所有操作。此外,最好不要修改输入,而是返回修改后的副本。虽然,这最终将是你的决定。 最后,您可以在断开循环时使用 for/else 来代替标记。
这是一个简单的实现
def update(input_data, input_calls):
for _id, ind, cond, val in input_data:
for call in input_calls:
if ind['ind'] in call:
yield [_id,
{'ind': ind['ind']},
{'cond': cond['cond']},
{'val': call[-1]} #here it updates the value
]
break
else:
yield row
input_data = [['random', {'ind': 'RSI_15'}, {'cond': '<'}, {'val': 12}], ['random', {'ind': 'volume'}, {'cond':'>'}, {'val': 44}]]
input_calls = [['ddd', 1000], ['volume', 1000], ['RSI_15', 15]] #testing odd calls
updated_data = list(update(input_data, input_calls))
print(updated_data)
#[['random', {'ind': 'RSI_15'}, {'cond': '<'}, {'val': 15}], ['random', {'ind': 'volume'}, {'cond': '>'}, {'val': 1000}]]
1赞
JustLearning
11/17/2023
#3
按照 for 循环的逻辑,这里有一个改进的方法:
for opt in opti:
for sublist in list2:
indicator_detected = False
for elem in sublist:
if isinstance(elem, dict):
if list(elem.values())[0] == opt[0]:
indicator_detected = True
if indicator_detected:
for elem in sublist:
if isinstance(elem, dict):
if list(elem.keys())[0] == 'val':
elem['val'] = opt[1]
也就是说,检查每个子列表的一个元素是否是字典,以及该字典是否具有给定的键,可以像其他答案所示,使用和理解以不那么麻烦(可能更快)的方式编写。any
下一个:字典查找错误请求 400
评论
v['ind'] == indicator
什么都不做。它比较了指标,但它不是指标的一部分,所以什么也没发生。if
v['ind']
opti = [['volume', 1000], ['RSI_15', 15]]