Как изменить записи списка во время цикла?

Теперь я знаю, что небезопасно изменять список во время итеративного цикла. Однако предположим, что у меня есть список строк, и я хочу разбить строки. Меняется ли замена измененных значений как модификация?

Ответ 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']