为什么这是索引错误?

Why is this an index error?

这是我的第一个 post,如果之前有人回答过这个问题,我深表歉意。我试图查看有关字符串格式和列表的 Python 3 文档,并在 SO 上查看了类似的格式问题。

我想将字符串 (data1) 分解成一个列表 (bigData),然后使用列表项打印出一条语句。 最终,我的想法是读取一个 csv 文件,将其分解,然后打印出一个响应,但由于出现错误,我试图简化该过程。

"Hello, John Doe. Your current balance is .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))

我的猜测是大数据是异构的,这意味着一个元组。如果我替换为字符串值而不是 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 中编写此作品?

谢谢。

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

print(greeting.format(*bigData))

此外,您可能需要:

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

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 returns 是一个列表。

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

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

% 格式化不会遇到此错误,因为它实际上需要一个元组(或一个项目)在正确的 ope运行d 中。

一个更通俗易懂的方法实际上可能是已经转到 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 可能更适合这种用途。

str.split() 方法 returns 列表,根据定义。

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