这个字典理解与这个 "for" 循环有什么不同?
How does this dictionary comprehension differ from this "for" loop?
我已经尝试过使用字典理解和 for 循环来实现一个算法,我相信这两者都可以达到相同的结果。
词典理解
for i in range(num_iter):
new_state_values = {s: get_new_state_value(mdp, state_values, s, gamma) for s in mdp.get_all_states()}
for 循环
for i in range(num_iter):
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
当我的算法运行时,它们会得到非常不同的结果。谁能指出两者的区别?
详情
完整算法如下
# parameters
gamma = 0.9 # discount for MDP
num_iter = 100 # maximum iterations, excluding initialization
min_difference = 0.001 # stop VI if new values are this close to old values (or closer)
# initialize V(s)
state_values = {s: 0 for s in mdp.get_all_states()}
for i in range(num_iter):
new_state_values = {s: get_new_state_value(mdp, state_values, s, gamma) for s in mdp.get_all_states()}
# Compute difference
diff = max(abs(new_state_values[s] - state_values[s]) for s in mdp.get_all_states())
state_values = new_state_values
if diff < min_difference:
print("Terminated")
break
'for-loop' 版本几乎没有运行任何迭代,而字典理解运行了更多的迭代。
update:上面的代码有效并收敛(我想这是最pythonic的,imo)。接受的答案提供了对不同方法的深入了解。
non-comprehension 版本会累积值,而不会丢弃先前运行的外循环中的值。如果你想让它等价,你需要改变:
for i in range(num_iter):
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
至:
for i in range(num_iter):
new_state_values = {} # NEW!!!
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
将 new_state_values
重新初始化为干净的 dict
。
在您的完整代码中,non-comprehension 解决方案会将 state_values
和 new_state_values
作为 same dict
的别名] (所以 state_values
会随着你的使用而改变),使问题变得更糟; dict
理解通过构建一个新的 dict
来修复它,而不修改正在构建的 state_values
。
我已经尝试过使用字典理解和 for 循环来实现一个算法,我相信这两者都可以达到相同的结果。
词典理解
for i in range(num_iter):
new_state_values = {s: get_new_state_value(mdp, state_values, s, gamma) for s in mdp.get_all_states()}
for 循环
for i in range(num_iter):
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
当我的算法运行时,它们会得到非常不同的结果。谁能指出两者的区别?
详情
完整算法如下
# parameters
gamma = 0.9 # discount for MDP
num_iter = 100 # maximum iterations, excluding initialization
min_difference = 0.001 # stop VI if new values are this close to old values (or closer)
# initialize V(s)
state_values = {s: 0 for s in mdp.get_all_states()}
for i in range(num_iter):
new_state_values = {s: get_new_state_value(mdp, state_values, s, gamma) for s in mdp.get_all_states()}
# Compute difference
diff = max(abs(new_state_values[s] - state_values[s]) for s in mdp.get_all_states())
state_values = new_state_values
if diff < min_difference:
print("Terminated")
break
'for-loop' 版本几乎没有运行任何迭代,而字典理解运行了更多的迭代。
update:上面的代码有效并收敛(我想这是最pythonic的,imo)。接受的答案提供了对不同方法的深入了解。
non-comprehension 版本会累积值,而不会丢弃先前运行的外循环中的值。如果你想让它等价,你需要改变:
for i in range(num_iter):
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
至:
for i in range(num_iter):
new_state_values = {} # NEW!!!
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
将 new_state_values
重新初始化为干净的 dict
。
在您的完整代码中,non-comprehension 解决方案会将 state_values
和 new_state_values
作为 same dict
的别名] (所以 state_values
会随着你的使用而改变),使问题变得更糟; dict
理解通过构建一个新的 dict
来修复它,而不修改正在构建的 state_values
。