Этот вопрос уже имеет ответ здесь:
Я пытаюсь изменить объекты в списке с помощью для цикла, но я получаю ошибку (см. ниже). Пример кода:
#!/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
data[item] = "everything"
TypeError: list indices must be integers, not str
Там какой-либо путь состоит в том, чтобы решить эту проблему?
Попробуйте вместо этого следующее:
for i in xrange(len(data)):
data[i] = "everything"
Основная проблема заключается в том, что когда вы пишете data[i]
, а data
- это список, i
должно быть целым числом, числовым индексом списка. Но в цикле
for item in data
item
- это собственно вещь, которая находится в списке, т.е. строка, а не числовой индекс вещи. xrange
- это итератор, который выдает числа вместо значений в списке, поэтому вы можете использовать его.
Альтернативой может быть
for i, _ in enumerate(data):
data[i] = "everything"
Функция enumerate
дает итератор по кортежам вида (index, item)
, так что все, что вам нужно сделать, это взять индекс и забыть об элементе. Я не уверен, что тот или иной способ (enumerate
или xrange
) будет значительно быстрее или лучше, поскольку, как мне кажется, списки хранят свою длину в переменной, чтобы к ней можно было быстро получить доступ без перебора элементов списка.
Однако, если вам нужно старое значение списка для вычисления нового значения списка, способ enumerate
, вероятно, будет немного быстрее, потому что вы избежите необходимости заставлять Python искать элемент в списке:
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]
Доступ к элементам списка осуществляется по целочисленному индексу, т.е. в вашем примере data[1] == 'example'
. Вот почему Python жалуется, когда вы используете строку в качестве поиска.
Если вы хотите найти элемент в списке по его значению, вы можете использовать data.index("value")
:
data[data.index("some")] = "something else"
Но если вы хотите просто перебрать их, используйте enumerate()
, как предложил Дэвид.