如何在 Python 中解包嵌套元组?

3 投票
3 回答
2436 浏览
提问于 2025-04-18 11:00

假设我有一些用户(约翰、安娜),他们可以选择自己想要的水果(橙子、苹果)并下订单。

这是我在Python中写的代码:

orders = (('John', (('apples', 3), ('oranges', 1))),
          ('Anna', (('oranges', 6))))

我想要遍历这些订单:

for user, order in orders:
    for fruit, quantity in order:
        print "%s wants %d %s" % (user, quantity, fruit)

这是我期望的输出结果:

John wants 3 apples
John wants 1 oranges
Anna wants 6 oranges

但是我遇到了一个错误,提示 ValueError: too many values to unpack。我哪里做错了呢?我是不是应该用其他的东西而不是元组?还是说我的遍历方式有问题?

3 个回答

0

我会用 list(x),而不是 dict(dict),这里的 x 是一个简单的类,用来表示一个人。

class Buyer(object):
  def __init__(self, name):
    self.name = name
    self.items = {}

  def purchase(self, item, amount=1):
    if item in self.items.keys():
      self.items[item] += amount
    else:
      self.items[item] = amount

orders = []

b1 = Buyer("John")
b1.purchase("apples", 3)
b1.purchase("oranges", 1)
orders.append(b1)

b2 = Buyer("Anna")
b2.purchase("oranges", 6)
orders.append(b2)

for order in orders:
  for thing, num in order.items.iteritems():
    print "%s wants %d %s" % (order.name, num, thing)
2

Daniel 对以下问题给出了很好的回答:

我哪里做错了?

但为了回答你的第二个问题:

我应该使用其他东西而不是元组吗?

我认为用字典会更合适:

>>> orders = {'John': {'apples': 3, 'oranges': 1}, 'Anna': {'oranges': 6}}
>>> for user, order in orders.items():
        for fruit, quantity in order.items():
            print "{0} wants {1} {2}".format(user, quantity, fruit)


Anna wants 6 oranges
John wants 1 oranges
John wants 3 apples

(注意,字典不保证保持内容的顺序——如果顺序很重要,可以使用一种替代方案collections.OrderedDict,它可以保证保持插入顺序。)

这在回答像"约翰想要多少个苹果?"这样的问题时特别有用。

>>> orders['John']['apples']
3

你也可以修改这个问题,以防有人没有订购那个水果,比如你想知道"总共订购了多少个苹果?"

>>> sum(order.get('apples', 0) for order in orders.values())
3
7

如果能展示具体的错误信息就好了。

这个错误的原因很简单,Anna的订单其实并不是一个嵌套的元组,而是一个普通的元组。你在最后缺少了一个逗号:

orders = (('John', (('apples', 3), ('oranges', 1))),
          ('Anna', (('oranges', 6),)))
#                                 ^ here

记住,决定元组的关键是逗号,而不是括号。

不过,正如其他人所说,这里用嵌套字典会更合适。

撰写回答