【问题标题】:Tuple Unpacking - ValueError元组解包 - ValueError
【发布时间】:2016-06-21 10:47:54
【问题描述】:

这里的问题很简单。我似乎无法解决它。

基本上,我在该存储库存数据中有一个包含多个元组的字典。

例如

portfolio = [('25-Jan-2001', 43.5, 25, 'CAT', 92.45),
('25-Jan-2001', 42.8, 50, 'DD', 51.19),
('25-Jan-2001', 42.1, 75, 'EK', 34.87),
('25-Jan-2001', 37.58, 100, 'GM', 37.58)]

我正在尝试拆开包装并将购买价格乘以股票数量。最终将它们加在一起。

def total_purchase_price(portfolio):
    purdate, purprice, numshares, sym, curprice = portfolio
    totalprice = 0
    for i in portfolio: 
        totalprice = purprice[i] * numshares[i]
        print(totalprice)
    return

但是,我得到一个 ValueError: need more than 4 values to unpack。

这是因为字符串不是整数吗?

任何帮助将不胜感激。谢谢

【问题讨论】:

  • 你解包的方式,你期望你的数据结构是这样的:('25-Jan-2001', 43.5, 25, 'CAT', 92.45)。情况并非如此,因为您提供的是元组列表。
  • 你认为i在你的for循环中的价值是什么?
  • 你也应该使用unpack 吗?即使没有它,你也可以做到

标签: python python-3.x dictionary tuples


【解决方案1】:

portfolio 是一个包含 4 个元组的列表。这行代码:

purdate, purprice, numshares, sym, curprice = portfolio

正在尝试将该列表解压缩为 5 个变量,但由于其中只有四个项目而失败。我怀疑您想要编写类似以下模式的代码:

# iterate through the items in the portfolio
for item in portfolio:
    # for each item, unpack the tuple into its constituent parts
    purdate, purprice, numshares, sym, curprice = item
    # ...do some calculations on those values

【讨论】:

  • 或者更规范地说,直接解压:for purdate, purprice, numshares, sym, curprice in portfolio:。它甚至可以使代码在启动时运行得更快一些,特别是对于某些内置的生成器返回函数,例如zip 和许多在 itertools 模块中生成 tuples 的函数,如果在 Python 代码中不保留对 tuple 的引用,则生成器可以一遍又一遍地重新填充相同的 tuple 而无需返回新的每次一个。
【解决方案2】:

如果你想要总和,你可以在循环中使用 sum 函数解包:

def total_purchase_price(portfolio):
    return sum(pp * sh for _, pp, sh, _, _ in portfolio)

或者使用 python3 和extended iterable unpacking:

def total_purchase_price(portfolio):
    return sum(pp * sh for _, pp, sh, *_ in portfolio)

或者如果你喜欢函数式,你可以使用itertools.starmap的一些运算符方法:

from operator import mul, itemgetter
from itertools import starmap


def total_purchase_price(portfolio):
    return sum(starmap(mul, map(itemgetter(1,2), portfolio)))

【讨论】:

    【解决方案3】:

    bgporter 的反应很好,可能是您正在寻找的。您将元组解包到您自己的数组中的初衷也是可以实现的:

    def total_purchase_price(portfolio):
        purdate, purprice, numshares, sym, curprice = zip(*portfolio)
        totalprice = 0
        for i in range(len(portfolio)):
            totalprice = purprice[i] * numshares[i]
            print(totalprice)
        return
    

    请注意 zip(*portfolio) 本质上解压缩了投资组合列,以及 for 循环中的 range(len(portfolio)) 以获取正确的长度。结果:

    1087.5
    2140.0
    3157.5
    3758.0
    

    为了简单和可读性,我仍然更喜欢@bgporter,但这种方法是可行的。

    对于典型答案,我会这样做:

    def total_purchase_price(portfolio):
        def px(row):
            purdate, purprice, numshares, sym, curprice = row
            return purprice * numshares
        print sum(map(px, portfolio))
    

    【讨论】:

    • 很好——我不会想到这种柱状方法。
    【解决方案4】:

    感谢@bgporter 和@F1Rumors!

    我对此的回答:

    def total_purchase_price(portfolio):
        totalprice = 0
        totalpurprice = 0
        for item in portfolio:
            purdate, purprice, numshares, sym, curprice = item
            totalprice += purprice * numshares
            totalpurprice = totalprice
        print(totalpurprice)
        return
    

    我可能可以使用@F1Rumors 的建议来减少它,但现在就可以了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 2017-08-05
      • 2015-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多