【问题标题】:Value Error: too many values to unpack (expected 3)值错误:要解压的值太多(预期为 3)
【发布时间】:2019-01-13 11:49:10
【问题描述】:

我试图实现值迭代算法。 我有一个网格

grid = [[0, 0, 0, +1],
    [0, "W", 0, -1],
    [0, 0, 0, 0]]

行动清单

actlist = {UP:1, DOWN:2, LEFT:3, RIGHT:4}

还有一个奖励函数

reward = [[0, 0, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0,  0]] 

我写了一个函数 T,它返回 3 个元组的元组。

def T(i,j,actions):
if(i == 0 and j == 0):
    if(actions == UP):
        return (i,i,0.8),(i,i,0.1),(i,j+1,0.1)
    elif(actions == DOWN):
        return (i+1,j,0.8),(i,j,0.1),(i,j+1,0.1)
    elif(actions == LEFT):
        return (i,j,0.8),(i,j,0.1),(i+1,j,0.1)
    elif(actions == RIGHT):
        return (i,j+1,0.8),(i,i,0.1),(i+1,j,0.1)
elif (i == 0 and j == 1):
    if(actions == UP):
        return (i,i,0.8),(i,j-1,0.1),(i,j+1,0.1)
    elif(actions == DOWN):
        return (i,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
    elif(actions == LEFT):
        return (i,j-1,0.8),(i,j,0.1),(i,j,0.1)
    elif(actions == RIGHT):
        return (i,j+1,0.8),(i,j,0.1),(i,j,0.1)
elif(i == 0 and j == 2):
    if(actions == UP):
        return (i,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
    elif(actions == DOWN):
        return(i+1,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
    elif(actions == LEFT):
        return (i,j-1,0.8),(i,j,0.1),(i+1,j,0.1)
    elif(actions == RIGHT):
        return (i,j+1,0.8),(i,j,0.1),(i+1,j,0.1)
elif(i == 0 and j == 3):
    if(actions == UP):
        return (-1,-1,0.8),(-1,-1,0.1),(-1,-1,0.1)
    elif(actions == DOWN):
        return (-1,-1,0.8),(-1,-1,0.1),(-1,-1,0.1)
    elif(actions == LEFT):
        return (-1,-1,0.8),(-1,-1,0.1),(-1,-1,0.1)
    elif(actions == RIGHT):
        return (-1,-1,0.8),(-1,-1,0.1),(-1,-1,0.1)
# 2nd row
elif (i == 1 and j == 0):
    if(actions == UP):
        return (i-1,j,0.8),(i,j,0.1),(i,j,0.1)
    elif(actions == DOWN):
        return (i+1,j,0.8),(i,j,0.1),(i,j,0.1)
    elif(actions == LEFT):
        return (i,j,0.8),(i-1,j,0.1),(i+1,j,0.1)
    elif(actions == RIGHT):
        return (i,j,0.8),(i-1,j,0.1),(i+1,j,0.1)
elif(i == 1 and j ==1):
    if(actions == UP):
        return (i,j,0.8),(i,j,0.1),(i,j,0.1)
    elif(actions == DOWN):
        return (i,j,0.8),(i,j,0.1),(i,j,0.1)
    elif(actions == LEFT):
        return (i,j,0.8),(i,j,0.1),(i,j,0.1)
    elif(actions == RIGHT):
        return (i,j,0.8),(i,j,0.1),(i,j,0.1)
elif (i == 1 and j == 2):
    if(actions == UP):
        return (i-1,j,0.8),(i,j,0.1),(i,j+1,0.1)
    elif(actions == DOWN):
        return (i+1,j,0.8),(i,j,0.1),(i,j+1,0.1)
    elif(actions == LEFT):
        return (i,j,0.8),(i-1,j,0.1),(i+1,j,0.1)
    elif(actions == RIGHT):
        return (i,j+1,0.8),(i-1,j,0.1),(i+1,j,0.1)
elif(i == 1 and j == 3):
    if(actions == UP):
        return (-2,-2,0.8),(-2,-2,0.1),(-2,-2,0.1)
    elif(actions == DOWN):
        return (-2,-2,0.8),(-2,-2,0.1),(-2,-2,0.1)
    elif(actions == LEFT):
        return (-2,-2,0.8),(-2,-2,0.1),(-2,-2,0.1)
    elif(actions == RIGHT):
        return (-2,-2,0.8),(-2,-2,0.1),(-2,-2,0.1)      
# 3rd row
elif(i == 2 and j == 0):
    if(actions == UP):
        return (i-1,j,0.8),(i,j,0.1),(i,j+1,0.1)
    elif(actions == DOWN):
        return (i,j,0.8),(i,j,0.1),(i,j+1,1,0.1)
    elif(actions == LEFT):
        return (i,j,0.8),(i-1,j,0.1),(i,j,0.1)
    elif(actions == RIGHT):
        return (i,j+1,0.8),(i-1,j,0.1),(i,j,0.1)
elif (i == 2 and j == 1):
    if(actions == UP):
        return (i,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
    elif(actions == DOWN):
        return (i,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
    elif(actions == LEFT):
        return (i,j-1,0.8),(i,j,0.1),(i,j,0.1)
    elif(actions == RIGHT):
        return (i,j+1,0.8),(i,j,0.1),(i,j,0.1)
elif(i == 2 and j == 2):
    if(actions == UP):
        return (i-1,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
    elif(actions == DOWN):
        return (i,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
    elif(actions == LEFT):
        return (i,j-1,0.8),(i-1,j,0.1),(i,j,1)
    elif(actions == RIGHT):
        return (i,j+1,0.8),(i-1,j,0.1),(i,j,0.1)
elif(i == 2 and j == 3):
    if(actions == UP):
        return (i-1,j,0.8),(i,j-1,0.1),(i,j,0.1)
    elif(actions == DOWN):
        return (i,j,0.8),(i,j-1,0.1),(i,j,0.1)
    elif(actions == LEFT):
        return (i,j-1,0.8),(i-1,j,0.1),(i,j,0.1)
    elif(actions == RIGHT):
        return (i,j,0.8),(i-1,j,0.1),(i,j,0.1) 

这个函数在值迭代函数中被调用:

def value_iteration():
U1 = [[0, 0, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 0]] 
while True:
    U=U1.copy()
    delta = 0
    for i in range(len(grid)):
        for j in range(len(grid[i])):
            U1[i][j] = max(sum(p*(R(k,l)+gamma*U[k][l]) for (k,l,p) in T(i,j,a)) for a in actlist)
            print(i,j,U1[i][j])
            delta = max(delta, abs(U1[i][j] - U[i][j]))
    if delta <= epsilon*(1 - gamma)/gamma:
        return U

问题是,for 循环的前两次迭代输出良好

0 0
0 1
0 2
0 3
1 0
1 1
1 2 
1 3 

但随后代码因错误而停止

ValueError: too many values to unpack (expected 3)

【问题讨论】:

  • 您能否提供完整的错误消息,以便我们知道错误的确切触发位置?
  • U1[i][j] = max(sum(p*(R(k,l)+gamma*U[k][l]) for (k,l,p) in T(i,j,a)) for a in actlist)此行触发错误。
  • 附带问题:如果您的所有功能都像表格一样,为什么不使用字典?
  • @EdwardMinnix,我不知道该怎么做。
  • @ShifatEArman 您只需创建一个字典,其中键是 3 元素元组,其值为 (i, j, action),其值是您将从函数返回的结果(尽管它们需要硬编码。如果你对字典不熟悉,我建议你参考the official documentation

标签: python python-3.x tuples artificial-intelligence valueerror


【解决方案1】:

正如@EdwardMinnix 提到的,您应该使用 map 并且永远不要进行这种 if/else 构造。或者,如果有任何具有这些值的模式,请查看 Stragety Pattern

这会对你有所帮助:

...

VALUE_A = 0.8
VALUE_B = 0.1


def new_T(i, j, actions):
    result_map = {(0, 0, 1): ((i, i, VALUE_A), (i, i, VALUE_B), (i, j + 1, VALUE_B)),
              (0, 0, 2): ((i + 1, j, VALUE_A), (i, j, VALUE_B), (i, j + 1, VALUE_B)),
              (0, 0, 3): ((i, j, VALUE_A), (i, j, VALUE_B), (i + 1, j, VALUE_B)),
              (0, 0, 4): ((i, j + 1, VALUE_A), (i, i, VALUE_B), (i + 1, j, VALUE_B)),
              (0, 1, 1): ((i, i, VALUE_A), (i, j - 1, VALUE_B), (i, j + 1, VALUE_B)),
              (0, 1, 2): ((i, j, VALUE_A), (i, j - 1, VALUE_B), (i, j + 1, VALUE_B)),
              (0, 1, 3): ((i, j - 1, VALUE_A), (i, j, VALUE_B), (i, j, VALUE_B)),
              (0, 1, 4): ((i, j + 1, VALUE_A), (i, j, VALUE_B), (i, j, VALUE_B)),
              (0, 2, 1): ((i, j, VALUE_A), (i, j - 1, VALUE_B), (i, j + 1, VALUE_B)),
              (0, 2, 2): ((i + 1, j, VALUE_A), (i, j - 1, VALUE_B), (i, j + 1, VALUE_B)),
              (0, 2, 3): ((i, j - 1, VALUE_A), (i, j, VALUE_B), (i + 1, j, VALUE_B)),
              (0, 2, 4): ((i, j + 1, VALUE_A), (i, j, VALUE_B), (i + 1, j, VALUE_B))}

    return result_map.get((i, j, actions))


for i, j, action in itertools.product(range(4), range(4), range(1, 5)):
    print('%s %s %s' % (i, j, action))
    T_value = T(i, j, action)
    new_T_value = new_T(i, j, action)
    if T_value != new_T_value:
        raise AssertionError('Error! \nT:     %s \nNew T: %s' % (T_value, new_T_value))

【讨论】:

    【解决方案2】:

    看看** **中的元组,可能就是这个原因

    # 3rd row
    elif(i == 2 and j == 0):
        if(actions == UP):
            return (i-1,j,0.8),(i,j,0.1),(i,j+1,0.1)
        elif(actions == DOWN):
            return (i,j,0.8),(i,j,0.1),**(i,j+1,1,0.1)**
        elif(actions == LEFT):
            return (i,j,0.8),(i-1,j,0.1),(i,j,0.1)
        elif(actions == RIGHT):
            return (i,j+1,0.8),(i-1,j,0.1),(i,j,0.1)
    elif (i == 2 and j == 1):
        if(actions == UP):
            return (i,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
        elif(actions == DOWN):
            return (i,j,0.8),(i,j-1,0.1),(i,j+1,0.1)
        elif(actions == LEFT):
            return (i,j-1,0.8),(i,j,0.1),(i,j,0.1)
        elif(actions == RIGHT):
           return (i,j+1,0.8),(i,j,0.1),(i,j,0.1)
    

    【讨论】:

    • 愚蠢的错误。非常感谢。 :)
    • 当然。另一件事,在两个 for 循环完成后,我正在更新 U=U1.copy()。但它会在我的 for 循环中自动更新。我不明白原因。
    • 不确定是否能解决您的问题,但每次使用该功能时,您都会“重置”UU1 并返回 U,这只是零
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    相关资源
    最近更新 更多