Python 值错误:解包的值过多

169 投票
3 回答
454690 浏览
提问于 2025-04-16 23:33

我在这段代码中遇到了一个异常:

class Transaction:
    def __init__ (self):
        self.materials = {}

    def add_material (self, m):
        self.materials[m.type + m.purity] = m

    def serialize (self):
        ser_str = 'transaction_start\n'

        for k, m in self.materials:
            ser_str += m.serialize ()

        sert += 'transaction_end\n'
        return ser_str

出问题的地方是在 for 这一行。这里的 mMaterial 对象。有没有人知道为什么会这样?

3 个回答

19

遍历一个字典对象时,实际上你得到的是它的 的迭代器。Python 正在尝试将从 m.type + m.purity 得到的键解包到 (m, k) 中。

根据我的推测,m.typem.purity 都是字符串,所以你的键也是字符串。字符串是可以被遍历的,这意味着它们可以被解包;但是遍历字符串时,你得到的是它的字符的迭代器。因此,每当 m.type + m.purity 的长度超过两个字符时,你就有太多的值需要解包了。(而每当它的长度小于两个字符时,你又有太少的值可以解包。)

要解决这个问题,你可以明确地遍历字典的 items,这些就是你似乎在期待的 (键, 值) 对。如果你只想要值,那就直接使用值就可以了。

(在 Python 2.x 中,itervaluesiterkeysiteritems 通常是更好的选择;非 iter 版本会创建一个新的列表对象,包含值/键/项。对于大型字典和简单的遍历任务,这可能比 iter 版本慢很多,因为后者只是设置了一个迭代器。)

84
for k, m in self.materials.items():

例子:

miles_dict = {'Monday':1, 'Tuesday':2.3, 'Wednesday':3.5, 'Thursday':0.9}
for k, v in miles_dict.items():
    print("%s: %s" % (k, v))
192

self.materials 是一个 dict(字典),默认情况下,你只是在遍历它的键(这些键是字符串)。

因为 self.materials 有超过两个键*,所以它们不能被拆分成 tuple(元组) "k, m",因此会引发 ValueError 异常

在 Python 2.x 中,如果想同时遍历键和值(即 tuple "k, m"),我们可以使用 self.materials.iteritems()

不过,因为你反正是要丢掉键,所以可以直接遍历字典的值:

for m in self.materials.itervalues():

在 Python 3.x 中,建议使用 dict.values()(它返回一个 字典视图对象):

for m in self.materials.values():

撰写回答