当数组中元素的 len 大于 2 时,“解包的值太多(预期为 2)”

Posted

技术标签:

【中文标题】当数组中元素的 len 大于 2 时,“解包的值太多(预期为 2)”【英文标题】:"too many values to unpack (expected 2)" when the len of element in array is more than 2 【发布时间】:2022-01-14 13:49:28 【问题描述】:

也许问这个问题会很奇怪,因为我当然不明白。

例如,如果我们有a=[(1,2), (3,4)];操作有效

for x,y in a:
    print(x,y)

但只要我们向这些元组添加任何其他元素,a=[(1,2,3),(4,5,6)]

for x,y in a:
    print(x,y)
---------------
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

但是使用zip(a[0],a[1]) 可以工作

我看到这个问题之前已经被问过很多次了,但我找不到任何可以解释为什么 len 超过 2 不起作用。

谁能给我解释一下为什么会这样?

【问题讨论】:

您只能将一个可迭代对象解压缩为精确数量的变量,作为通过迭代获得的元素。如果您只对元组的前两个元素感兴趣并希望丢弃其余元素,请执行for x, y in (t[:2] for t in a): 之类的操作。但是因为你没有说你期望什么输出,所以很难知道你的要求是什么。 另请注意,您的 zip 示例产生的元素分组与第一个 2x2 示例中显示的简单迭代完全不同,因此当您说它“有效”时,它不会引发异常,但是这可能不同于说它给出了预期的结果。 @PatXio 请务必提供反馈并选择回答您问题的答案,以便其他人也可以受益 【参考方案1】:

好问题。

对于a=[(1,2), (3,4)],了解这些数据结构是什么很重要。

a 是 list 的 tuples。所以a[0](1,2)a[1](3,4)

因此,如果您向其中一个元组添加更多元素,您实际上不会更改a。因为,请记住,a 只是元组。您正在更改元组中的值。因此,a 的长度永远不会改变。

如果你想访问所述元组的值,你可以这样做 print(a[0][0]) 产生0

一个示例程序,看看我的意思:

a = [(1,2), (3,4)]
b = [(1,2,3), (4,5,6)]

def understand_data(x):
    print("First, let's loop through the first structure and see what it is")
    print("You passed in: ".format(type(x)))


    print("Now printing type and contents of the passed in object")
    for i in range(len(x)):
        print(type(x[i]))
        print(x[i])

    print("Now printing the contents of the contents of the passed in object")
    for i in range(len(x)):
        for j in range(len(x[i])):
            print(x[i][j])

    print("DONE!")

understand_data(a)
understand_data(b)

产量:

[Running] python -u "c:\Users\Kelly\wundermahn\example.py"
First, let's loop through the first structure and see what it is
You passed in: <class 'list'>
Now printing type and contents of the passed in object
<class 'tuple'>
(1, 2)
<class 'tuple'>
(3, 4)
Now printing the contents of the contents of the passed in object
1
2
3
4
DONE!
First, let's loop through the first structure and see what it is
You passed in: <class 'list'>
Now printing type and contents of the passed in object
<class 'tuple'>
(1, 2, 3)
<class 'tuple'>
(4, 5, 6)
Now printing the contents of the contents of the passed in object
1
2
3
4
5
6
DONE!

[Done] exited with code=0 in 0.054 seconds

【讨论】:

【参考方案2】:

too many values to unpack 被抛出,因为您试图将 3 个元素的元组解包(分配给变量)为 2 个变量 - xy

如果您的元组由 n 元素组成,您应该使用 n 变量解压缩它们,因此在您的情况下:

for x,y,z in a:
    pass

zip(a[0],a[1]) 为您工作的原因是因为zip 在您的示例中创建了一个包含 2 个元素元组的迭代器。例如,如果将其更改为 zip(a[0],a[1], a[2]),它将无法工作,因为将创建 3 个元素元组的迭代器,并且 2 个变量不足以解压它。

【讨论】:

【参考方案3】:

首先,尝试:

a = [(1, 2, 3), (4, 5, 6)]
for i in a:
    x, y, z = i
    print(x, y, z)

它应该返回:

1 2 3
4 5 6

变量 x 扮演托运人的角色,他将 3 个箱子从仓库 a 带到 3 个不同的客户 x、y、y。 接下来,如果托运人辞职了,那么这3个人需要自己去仓库。所以,我们有一个变化:

a = [(1, 2, 3), (4, 5, 6)]
for x, y, z in a:
    print(x, y, z)

它返回与上面相同的结果。 奖金,如果只有 2 位客户收到 3 盒。 x 得到一个盒子,y 得到两个。

a = [(1, 2, 3), (4, 5, 6)]
for x, *y in a:
    print(x, y)

输出:

1 [2, 3]
4 [5, 6]

希望有用!

【讨论】:

【参考方案4】:

因为a 中的元组每个都包含三个元素,所以您需要三个变量来解包它们。也就是说,

for x,y,z in a:
    ...

zip 示例有效的原因是,zip 从可迭代对象的各个元素(在本例中为元组)创建了一个元组。只有两个可迭代对象被传递给zip(即a[0]a[1])。这就是为什么你只需要两个变量来解压它们。

为了更好地看到这一点,请尝试运行以下代码:

for x in a:
    print(x)

您将看到需要三个变量来表示 x 的各个值。

然后看看输出:

for x in zip(a[0],a[1]):
    print(x)

【讨论】:

以上是关于当数组中元素的 len 大于 2 时,“解包的值太多(预期为 2)”的主要内容,如果未能解决你的问题,请参考以下文章

在训练 Bert 二进制分类模型时,Huggingface 变形金刚返回“ValueError:要解包的值太多(预期为 2)”

ValueError:使用 Sage 绘图时“解包的值太多”

ValueError:解包的值太多(Python 2.7)

Tensorboard - ValueError:解包的值太多(预期 2)

OpenCV python:ValueError:解包的值太多

如何修复:ValueError:解包的值太多(预期为 2)PCA