这个字典理解与这个 "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_valuesnew_state_values 作为 same dict 的别名] (所以 state_values 会随着你的使用而改变),使问题变得更糟; dict 理解通过构建一个新的 dict 来修复它,而不修改正在构建的 state_values