【问题标题】:' ValueError: too many values to unpack ''ValueError: 太多值无法解压'
【发布时间】:2020-01-20 19:16:02
【问题描述】:

我正在尝试编写扫雷的基本版本。您可以从用户那里获得行数、列数、炸弹及其位置。您应该计算每个元素周围的炸弹数量。考虑下面的例子: 输入

4 3
5
1 1
4 3
1 3
4 2
3 2

输出是:

* 2 *
2 3 2
2 * 3
2 * *

这是我的代码:

n, m = [int(x) for x in input().split()]


k = int(input()) #number of bombs

#location of bombs
bomb = []
for i in range(k):
    r,c = [int(r) - 1 for r in input().split()]
    bomb.append([r,c])

#making the grid
map = []
for x in range(n):
    map.append([])
    for y in range(m):
        map[x].append(0)

#locate bombs       
for i, j in bomb:
    map[i][j] = '*'

#count the bombs
Ns = 0
for i, j in map:
    for x in range(-1, 2):
        for y in range(-1, 2):
            if map[i + x][j + y] == '*':
                Ns += 1

    map[i][j] = Ns

print(map)

我的问题是在投降时找到炸弹。我得到ValueError: too many values to unpack for line 25。知道如何解决吗?

【问题讨论】:

  • 正确格式化代码..顺便说一句,这里n, m = [int(x) for x in input().split()] 您在rhs上有一个列表comps,它将为您提供一个列表类型的值..您正在尝试将其解压缩为2个变量这是不可能的。
  • 欢迎来到 SO! input() 接受参数提示。使用它很重要,否则用户将不知道要输入什么:input("please enter two numbers (rows, columns)") 等。为格式错误的输入添加错误处理并通常创建令人愉快的用户体验是个好主意。代码重新定义了内部map 函数——选择另一个变量名。 (这是对 Sam 的补充)。
  • shadi :您应该提供触发错误的输入。正如@SamDaniel 指出的那样,如果第一行传递了一个int,则会触发错误。如果接收到 2 个值就可以了。乍一看,您的代码的用法并不明显。同样在给出 python 错误时,告诉我们哪一行;它会让一切变得更容易。
  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确说明问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您指定的问题。您的代码不是最少的;当错误涉及第 24 行的三个变量时,为什么会有所有这些输入和设置代码?

标签: python nested-lists minesweeper


【解决方案1】:
for i, j in map:

无效。 map 是一个列表列表,类似于 4x3 数组。

您似乎试图遍历 map 的索引,并将它们与列表内容混淆。试试

for i in range(len(map)):
    for j in range(len(map[i])):
        ...

【讨论】:

    【解决方案2】:

    您的代码中存在两个潜在问题。

    首先,您的地图实际上有 3 个值要为每个值解包(因为您的 m 是 3),而不是两个。这是您需要修复的行:

    for i, j in map:

    相反,您可能需要解压缩 map 的每个值,如下所示:

    for x in range(len(map)):
        for y in range(len(map[i])):
            square = map[x][y]
    

    其次,您用于检查环境的代码可能会遇到问题,因为您只需将地雷的 x 和 y 减/加 1,这将使您的代码尝试在地图中查找不存在的索引!例如。如果 x 为 2,则增加 1 将为您提供 3,从而破坏您的列表。

    你可能想要的是:

    for i in range(max(0,x-1),min(x+1,n-1)+1):
        for j in range(max(0,y-1),min(y+1,m-1)+1):
    

    这仅接受环境中的值,并且不违反数组边界。 Max(0, x-1) 阻止我们给出负数组边界,而 min(x+1, n-1) 阻止我们超过最大数组边界。 y 也是如此。

    结合起来,代码可能看起来像这样:

    #count the bombs
    for x in range(len(map)):
        for y in range(len(map[i])):
            # if x,y is not a mine
            if map[x][y] != '*':
                # check the surroundings of x,y for mines
                Ns = 0
                for i in range(max(0,x-1),min(x+1,n-1)+1):
                    for j in range(max(0,y-1),min(y+1,m-1)+1):
                        # if this surrounding block is a mine, add to Ns
                        if (map[i][j]) == '*':
                            Ns += 1
                            print("Not safe: " + str(Ns))
                # append the Ns number to the x,y block
                map[x][y] = Ns
    
    for layer in map:
        print(layer)
    

    输出:

    ['*', 2, '*']
    [2, 3, 2]
    [2, '*', 3]
    [2, '*', '*']
    

    请注意,这绝对不是问题的最优化解决方案;最好的方法是在进行过程中保存值,这样我们就不必为每个图块检查所有 3 到 8 个周围图块,但希望这有助于您了解处理扫雷的基本情况.

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2015-12-20
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 2021-01-16
      • 2018-06-01
      相关资源
      最近更新 更多