Помогите разобраться с кодом!

a = ['egor', 'vika', 'max', 'egor2', 'egor3', 'egor4']

for x in a:
    if x.count('egor') > 0:
        a.remove(x)
    else:
        None
print(a)

По логике результат работы кода должен быть ['vika', 'max'], но по факту результат ['vika', 'max', 'egor3']! Не понимаю откуда берется 'egor3', объясните пожалуйста


Ответы (2 шт):

Автор решения: Fish228335

Проблема в твоем коде связана с изменением списка (a) во время его итерации в цикле for. Когда ты удаляешь элемент из списка a внутри цикла for, это влияет на индексацию элементов в списке.

Более безопасный способ удаления элементов из списка во время итерации - это создать новый список, содержащий только те элементы, которые ты хочешь сохранить. Вот исправленный код:

a = ['egor', 'vika', 'max', 'egor2', 'egor3', 'egor4']
a = [x for x in a if not x.count('egor') > 0]
print(a)

Этот код удалит все элементы, содержащие подстроку 'egor', и выведет ['vika', 'max'], как ожидалось.

→ Ссылка
Автор решения: MarianD

Примечание:

Сначала я исправил и немножко улучшил ваш код:

a = ['egor', 'vika', 'max', 'egor2', 'egor3', 'egor4']

for x in a[:]:                # (исправление)
    if 'egor' in x:           # (улучшение - в том числе и удалением лишней ветви else:)
        a.remove(x)
print(a)

Вывод:

['vika', 'max']

В чем ваша ошибка?

Вы проходите через тот же список, из которого вы удаляете элементы.

Здесь постепенное состояния списка и актуальная позиция (как ^):

a = ['egor', 'vika', 'max', 'egor2', 'egor3', 'egor4']    # перед входом в цикл
  ^

a = ['egor', 'vika', 'max', 'egor2', 'egor3', 'egor4']    # вход  в 1-ю итерацию
       ^

a = [        'vika', 'max', 'egor2', 'egor3', 'egor4']    # вход во 2-ю итерацию -  
               ^                                          # в предыдущей 'egor'удалился
               
a = [        'vika', 'max', 'egor2', 'egor3', 'egor4']    # вход  в 3-ю итерацию
                       ^

a = [        'vika', 'max', 'egor2', 'egor3', 'egor4']    # вход  в 4-ю итерацию
                               ^

a = [        'vika', 'max', 'egor3', 'egor4']             # вход  в 5-ю итерацию - 
                                        ^                 # в предыдущей 'egor2' удалился

a = [        'vika', 'max', 'egor3']                      # выход из 5-й итерации - в ней
                                        ^                 # 'egor4' удалился; актуальная 
                                                          # позиция за концом списка —   
                                                          # нет следующего элемента, 
                                                          # конец цикла

Как вы можете видеть, в списке остались точно те элементы, которые ваша программа и вывела.


Как я это исправил?

Очень просто — вместо вашей команды

for x in a:

я применил

for x in a[:]:

Объяснение:

a[:] сделает из списка a срез из всех элементов, и это копия оригинального списка - и она в цикле не меняется.


→ Ссылка