Теперь я знаю, что небезопасно изменять список во время итеративного цикла. Однако предположим, что у меня есть список строк, и я хочу разбить строки. Меняется ли замена измененных значений как модификация?
Как изменить записи списка во время цикла?
Ответ 1
Он считал бедную форму. Вместо этого используйте понимание списка с назначением среза, если вам нужно сохранить существующие ссылки на список.
a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print b
Ответ 2
Поскольку цикл ниже только изменяет уже увиденные элементы, он считается приемлемым:
a = ['a',' b', 'c ', ' d ']
for i, s in enumerate(a):
a[i] = s.strip()
print(a) # -> ['a', 'b', 'c', 'd']
Что отличается от:
a[:] = [s.strip() for s in a]
тем, что он не требует создания временного списка и его назначения для замены оригинала, хотя для этого требуется больше операций индексирования.
Предостережение: Хотя вы можете изменить записи таким образом, вы не можете изменить количество элементов в list
, не рискуя столкнуться с проблемами.
Вот пример того, что я имею в виду - удаление записи помешает индексированию с этой точки на:
b = ['a',' b', 'c ', ' d ']
for i, s in enumerate(b):
if s.strip() != b[i]: # leading or trailing whitespace?
del b[i]
print(b) # -> ['a', 'c ']
(Результат неверен, потому что он не удаляет все элементы, которые он должен иметь.)
Ответ 3
Еще один вариант цикла, выглядит более чистым для меня, чем один с enumerate():
for idx in range(len(list)):
list[idx]=... # set a new value
# some other code which doesn't let you use a list comprehension
Ответ 4
Нет, вы не изменили бы "контент" этого списка, если бы вы могли так изменить строки. Но на Python они не изменяются. Любая операция string возвращает новую строку.
Если у вас есть список объектов, которые, как вы знали, изменялись, вы можете сделать это, пока вы не измените фактическое содержимое списка.
Таким образом, вам нужно будет сделать какую-то карту. Если вы используете выражение генератора, то [операция] будет выполняться по мере повторения и вы сохраните память.
Ответ 5
Изменение каждого элемента при повторении списка в порядке, если вы не изменяете добавление/удаление элементов для списка.
Вы можете использовать понимание списка:
l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]
или просто выполните цикл C-style
for:
for index, item in enumerate(l):
l[index] = item.strip()
Ответ 6
Вы можете сделать что-то вроде этого:
a = [1,2,3,4,5]
b = [i**2 for i in a]
Он назвал понимание списка, чтобы упростить вам цикл внутри списка.
Ответ 7
Из вашего вопроса неясно, каковы критерии для принятия решения о том, какие строки удалить, но если у вас есть или может составить список строк, которые вы хотите удалить, вы можете сделать следующее:
my_strings = ['a','b','c','d','e']
undesirable_strings = ['b','d']
for undesirable_string in undesirable_strings:
for i in range(my_strings.count(undesirable_string)):
my_strings.remove(undesirable_string)
который меняет my_strings на ['a', 'c', 'e']