为什么这是索引错误?

时间:2017-08-25 15:17:39

标签: python list tuples string-formatting

这是我的第一篇文章,所以如果以前已经回答过,我会道歉。我试图查看有关字符串格式和列表的Python 3文档,并在此处查看类似的格式问题。

我想获取字符串(data1),将其分解为一个列表(bigData),并使用列表项打印出一个语句。 最终,想法是读取csv文件,分解并打印出响应,但我已经尝试简化过程,因为出现了错误。

  

"你好,John Doe。您目前的余额是53.44美元。"

但是,我不确定为什么下面的代码会抛出一个IndexError,更不用说是一个元组索引。

data1 = "John,Doe,53.44"
bigData = data1.split(",")
bigData[-1] = float(bigData[-1])

print(bigData) # test - []'s indicate a list, not tuple?

greeting = "Hello, {} {}. Your current balance is ${}."

print(greeting.format(bigData))

我的猜测是bigData是异构的,这意味着一个元组。如果我替换字符串值而不是53.44(因此data1和bigData是同类的),它会抛出相同的错误。

data1 = "John,Doe,random"
bigData = data1.split(",")

print(bigData) # test - []'s indicate a list, not tuple?

greeting = "Hello, {} {}. Your current balance is {}."

print(greeting.format(bigData))

但是,如果我将原始格式转换为Python 2.x字符串格式,它会正确格式化而不会出错。

data1 = "John,Doe,53.44"
bigData = data1.split(",")
bigData[-1] = float(bigData[-1])

print(bigData) # test - []'s indicate a list, not tuple?

greeting = "Hello, %s %s. Your current balance is $%.2f."

print(greeting % tuple(bigData))
  1. 为什么将我的字符串转换为元组?
  2. 如何在Python 3中编写这项工作?
  3. 谢谢。

4 个答案:

答案 0 :(得分:1)

使用splat(*)解压缩你的参数(你的format字符串需要三个参数,但你只给它一个,列表包含。)

print(greeting.format(*bigData))

另外,您可能需要:

bigData[-1] = str(round(float(bigData[-1]), 2))

答案 1 :(得分:0)

str.format方法采用位置参数,而不是单个列表。您需要使用bigData运算符解压缩列表*

data1 = "John,Doe,random"
bigData = data1.split(",")

print(bigData)  # test - []'s indicate a list, not tuple?

greeting = "Hello, {} {}. Your current balance is {}."

print(greeting.format(*bigData))  # here's the change

您确认bigData是一个列表,而不是一个元组,str.split会返回一个列表。

答案 2 :(得分:0)

我可以看到这是多么令人惊讶,但让我感到惊讶的是,回溯并未显示format调用中发生异常。

Python的列表可以像元组一样异构;这是因为它们存储的常见类型是对象引用,Python中的所有内容都是。元组实际上是format方法的参数列表,在本例中为(bigData,)。在查找要格式化的内容时,它会耗尽参数,因为您有三个{}占位符但只有一个参数(列表bigData)。您可以使用greeting.format(*bigData)解压缩列表并将其内容用作参数。

%格式化不会遇到此错误,因为它实际上需要右操作数中的元组(或一个项)。

更实用和清晰的方法实际上可能是转到csv模块:

import csv, io
data1 = "John,Doe,random"
for row in csv.DictReader(io.StringIO(data1),
        "givenname surname balance".split()):
    greeting = "Hello, {givenname} {surname}. Your current balance is {balance}."
    print(greeting.format(**row))

这允许我们为列分配有意义的名称,包括在需要时以格式字符串重新排序它们。我已经省略了浮动转换,顺便说一句,decimal.Decimal可能更适合这种用途。

答案 3 :(得分:0)

str.split()方法按定义返回一个列表。

我认为你误解了你读过的东西 - 异构与同类是指元组与列表的典型用例。让所有元素的类型匹配与否不会神奇地导致容器更改为其他类型!