31

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"

エラー:

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

この問題を解決する方法はありますか?

4

3 に答える 3

74

代わりにこれを試してください:

for i in xrange(len(data)):
    data[i] = "everything"

あなたが抱えている基本的な問題は、リストであると書くとき、リストへの数値インデックスである整数であるdata[i]必要があるということです。しかし、ループではdatai

for item in data

itemリストにある実際のもの、つまり文字列であり、ものの数値インデックスではありません。xrangeリスト内の値の代わりに数値を生成するイテレータなので、それを使用できます。

代替案は

for i, _ in enumerate(data):
    data[i] = "everything"

このenumerate関数は、フォームのタプルに対するイテレータを提供する(index, item)ので、インデックスを取得して項目を忘れるだけで済みます。リストはその長さを変数に格納するため、リスト要素をカウントせずにすばやくアクセスできると思うので、いずれかの方法 (enumerateまたは) が大幅に高速化または改善されるかどうかはわかりません。xrange

ただし、新しいリスト値を計算するために古いリスト値が必要な場合は、enumeratePython がリスト内の要素をルックアップするのを避けるため、この方法はおそらくわずかに高速になります。

for i, item in enumerate(data):
    data[i] = func(item)

ただし、この種のことは、リスト内包表記としてより適切に表現されます。

data = [func(item) for item in data]

これを行うと、Python は の各項目を調べて関数を適用し、結果から新しいリストを自動的に作成するので、 の結果をリストの正しい場所に配置するdataことを心配する必要はありません。func(item)元の例は、実際には次のように表現できます

data = ["everything" for item in data]
于 2010-07-04T06:24:15.920 に答える
5

リスト項目は、整数インデックスによってアクセスされます。つまり、あなたの例ではdata[1] == 'example'。これが、文字列をルックアップとして使用しているときに Python が文句を言う理由です。

リスト内の要素をその値で検索する場合は、次を使用できますdata.index("value")

data[data.index("some")] = "something else"

ただし、それらをループしたいだけの場合はenumerate()、Davidが提案したように使用してください。

于 2010-07-04T06:27:54.387 に答える
0

整数を使用したリストのインデックス付けは非効率的である可能性があります。Python は、基になるポインターを含むリンク テーブルを使用してリスト要素を格納する可能性があります。この場合、特定の項目を見つけるために、Python は i 番目の項目までリストをトラバースする必要があります。

次のような形式を使用すると効率的であることが示唆されています: a[:] = [x*x for x in a]

于 2015-08-06T14:34:51.493 に答える