【问题标题】:How to unpack nested tuples in python?如何在python中解压嵌套元组?
【发布时间】:2014-06-25 10:04:03
【问题描述】:

假设我的用户(约翰、安娜)可以根据自己的选择订购水果(橙子、苹果)。

这是我在 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。我究竟做错了什么? 我应该使用元组以外的东西吗?是不是我的迭代不好?

【问题讨论】:

    标签: python nested iteration tuples


    【解决方案1】:

    显示确切的回溯会很有用。

    错误只是 Anna 的 order 实际上不是嵌套元组:它是一个简单的元组。您在末尾缺少一个逗号:

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

    请记住,构成元组的是逗号,而不是括号。

    正如其他人所说,嵌套字典在这里更合适。

    【讨论】:

    • 回溯显示“太多值无法解包”的原因是因为它正在遍历 Anna 的订单,该订单首先尝试将 "oranges" 解包为两个变量,但不能。
    【解决方案2】:

    丹尼尔给出了一个很好的答案:

    我做错了什么?

    但是要解决您的第二个问题:

    我应该使用元组以外的东西吗?

    我会说这更适合dictionary

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

    【讨论】:

      【解决方案3】:

      好吧,我不会使用dict(dict),而是list(x),其中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)
      

      【讨论】:

      • 您可以更改它以将打印移动到例如Buyer.print_orders()
      • 你可以无限缩放这个:)
      猜你喜欢
      • 2013-01-22
      • 2021-06-01
      • 1970-01-01
      • 2019-04-21
      • 1970-01-01
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多