Python ValueError: too many values to unpack

169

我从这段代码中得到了异常:

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 对象。 有人有任何想法为什么会这样吗?


当我期望一个字典的值是一个元组列表时,我遇到了这个问题。相反,它创建了一个字符串列表 - 使用了元组的语法,我不得不去掉周围的括号,并在逗号处分割元组的组成部分。 - undefined
3个回答

192

self.materials是一个dict,默认情况下您只迭代键(它们是字符串)。

由于self.materials有两个以上的键*,它们无法解压缩为tuple "k, m",因此会引发ValueError exception

在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():

我不太明白这里,你为什么要说它有超过两个键? - Nuno Furtado
10
2.5年后,我只能猜测年少时的理由。接下来是我的猜想!如果self.materials中有零或一个键,我期望ValueError消息为“需要超过n个值进行解包”。如果恰好有两个键,则这些键将被解包为km(并且假定下一行会发生不同的错误)。三个或更多键?根据标题,会出现“ValueError:要解包的值太多”的错误。 - johnsyweb
1
哈哈,我甚至没有注意到这篇帖子的发布时间。我遇到了类似的问题,但我不明白为什么会出现那个错误,尽管如此,我还是使用了你的解决方案来解决这个问题。 - Nuno Furtado

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))

19

迭代字典对象本身实际上会给你一个包含 的迭代器。Python 试图将从 m.type + m.purity 获得的键解包成 (m, k)

我的预测是 m.typem.purity 都是字符串,因此你的键也是字符串。字符串是可迭代的,所以它们可以被解包;但是遍历字符串会给你一个字符的迭代器。所以每当 m.type + m.purity 长度超过两个字符时,你就有太多要解包的值了。(每当它更短时,你就有太少要解包的值了。)

要解决这个问题,你可以显式地迭代字典的 items,它们是你期望的 (key, value) 对。但如果你只想要值,那么就直接使用值。

(在 2.x 版本中,itervaluesiterkeysiteritems 通常是更好的选择;非 iter 版本会创建一个包含值/键/项的新列表对象。对于大型字典和迭代内部的简单任务,这比仅设置一个迭代器的 iter 版本要慢得多。)


谢谢。你的提示帮助我解决了更新形如{'longkey_n':['value_1','value_n']}的字典时遇到的问题:-D。我的程序也抱怨有太多的值... - Semo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接