与内联相比,在for循环中元组解包的行为

时间:2016-11-01 13:17:11

标签: python

我有一个非常简单的文本文件,就本例而言,它包含一个商店列表,其中包含相应的金额。 (制表符间距)文件如下所示:

7-Eleven     7.48
Paradies    28.00
Shoppers    68.26

我的目标是为7-Eleven以外的所有人计算金额。我的代码如下所示:

price = 0.0
with open('stores.txt', 'r') as f:
    for line in f:
        line = line.strip('\n').split('\t')
        for shop, priceStr in line:
            if not shop == '7-Eleven':
                price += float(priceStr)

可能有一些简化可以清理代码的中间部分,但是我遇到了“for shop,priceStr in line:”位的问题。我的理解是做“shop,priceStr”应该将当前行的内容解压缩为元组并将它们分配给变量shop和priceStr。但是,我收到错误:

ValueError: too many values to unpack

然而,如果我拿走当前行并将其解压缩到循环之外我会得到

shop, priceStr = line
print shop + ":" + priceStr

7-Eleven: 7.48

我不明白嵌套for循环和内联代码之间有什么不同。有人可以告诉我吗?此代码在python2.7和python3.4

中运行相同

由于

3 个答案:

答案 0 :(得分:3)

jasonharper的答案对于你的直接问题是正确的,但你可能在某些行中也有一个迷路\t,这会使天真的拆分方法将字符串拆分成两个以上的项目。

使用maxsplit参数限制拆分,这将忽略所有其他\t个字符:

line = line.split('\t', maxsplit=1)

或者通过将多余的项目(如果有的话)绑定到单独的变量来解压缩行,如下所示:

shop, priceStr, *rest = line
if rest:
    print("More than two items: {} {} {}".format(shop, priceStr, rest))

如果没有多余的项目,rest变量将是一个空列表。这将使您的代码在出现意外格式错误时更加健壮,然后您可以处理和/或报告。

答案 1 :(得分:2)

您可以告诉split只进行一次拆分,然后忽略任何可能的额外\t

line = line.strip('\n').split('\t', maxsplit=1)

如果您这样做,您可能还应strip每个解压缩的值都是安全的。如果float忽略空格,它可能没有它。

shop, priceStr = shop.strip(), priceStr.strip()

答案 2 :(得分:2)

执行line = line.strip('\n').split('\t')之后,line是一个包含两个元素的元组(假设没有其他海报指出的无关标签)。如果您对此进行迭代,您将首先获得商店名称,然后是价格。因此,当您执行for shop, priceStr in line:时,它会首先尝试将商店名称解压缩到您的两个变量中,然后尝试将价格解压缩到您的两个变量中;当然两种尝试都失败了。这里没有必要的迭代;您可以shop, priceStr = line将元组分解为两个元素,或者保存一行代码并直接执行shop, priceStr = line.strip('\n').split('\t')