修改循环中的列表项(python)

Mat*_*łło 29 python loops items

我正在尝试使用for循环修改列表中的项目,但是我收到错误(参见下文).示例代码:

#!/usr/bin/env python
# *-* coding: utf8 *-*

data = []
data.append("some")
data.append("example")
data.append("data")
data.append("here")

for item in data:
    data[item] = "everything"
Run Code Online (Sandbox Code Playgroud)

错误:

Traceback (most recent call last):
  File "./testy.py", line 11, in <module>
    data[item] = "everything"
TypeError: list indices must be integers, not str
Run Code Online (Sandbox Code Playgroud)

有什么方法可以解决这个问题吗?

Dav*_*d Z 70

试试这个:

for i in xrange(len(data)):
    data[i] = "everything"
Run Code Online (Sandbox Code Playgroud)

您遇到的基本问题是,当你写的data[i],有data是一个列表,则i需要是一个整数,数字索引列表.但在循环中

for item in data
Run Code Online (Sandbox Code Playgroud)

item是列表中的实际内容,即字符串,而不是事物的数字索引.xrange是一个迭代器,它生成数字而不是列表中的值,因此您可以使用它.

另一种选择

for i, _ in enumerate(data):
    data[i] = "everything"
Run Code Online (Sandbox Code Playgroud)

enumerate函数为您提供了一个表单元组的迭代器(index, item),因此您需要做的就是获取索引并忘记该项.我不确定一种方式或另一种方式(enumeratexrange)会明显更快或更好,因为我认为列表将它们的长度存储在变量中,因此可以快速访问它而无需计算列表元素.

但是,如果您需要旧的列表值来计算新的列表值,那么这种enumerate方式可能会稍快一些,因为您可以避免让Python查找列表中的元素:

for i, item in enumerate(data):
    data[i] = func(item)
Run Code Online (Sandbox Code Playgroud)

但是,这种事情更好地表达为列表理解:

data = [func(item) for item in data]
Run Code Online (Sandbox Code Playgroud)

执行此操作时,Python将遍历每个项目data,将函数应用于该项目,并自动从结果中构造新列表,因此您无需担心将结果func(item)放在列表中的正确位置.您的原始示例实际上可以表示为

data = ["everything" for item in data]
Run Code Online (Sandbox Code Playgroud)

  • @sigo:这实际上根本不是一种解决方法,它是100%正确且完全正常的方式来完成这类任务(但请注意我所说的关于列表推导的内容). (5认同)
  • 在这种特殊情况下,列表理解可以用更快的`data = ["everything"]*len(data)`来代替. (2认同)
  • 关于内存消耗和列表推导式的旁注:这将需要(临时)内存来存储旧的“数据”和新的“数据”。因此,对于大型列表,索引修改可能更可取。 (2认同)

Tim*_*ker 5

列表项由整数索引访问,即在您的示例中data[1] == 'example'.这就是当你使用字符串作为查找时Python抱怨的原因.

如果要按列值在列表中查找元素,可以使用data.index("value"):

data[data.index("some")] = "something else"
Run Code Online (Sandbox Code Playgroud)

但是,如果您只想循环遍历它们,请enumerate()按照David的建议使用.