В Python для удаления элементов из списка есть метод .pop()
и оператор del
. Но они изменяют изначальный список, что может привести к ошибкам в коде:
# Если удалять элементы в цикле
# то ломается порядок обхода
numbers = [1, 0, 2, 0, 3, 4]
for i in range(len(numbers)):
print('current elem = ', numbers[i])
if numbers[i] == 0:
numbers.pop(i)
#=> current elem = 1
#=> current elem = 0
# 0
#=> current elem = 0
# 0
#=> current elem = 4
# IndexError: list index out of range
В примере выше мы получили ошибку, потому что удаляя элемент мы смещаем указатель дальше по списку, и перепрыгиваем элементы.
При этом задача удаления возникает регулярно. Причем обычно удаляется не один элемент, а набор элементов по определенным правилам. Например, довольно распространена операция compact – удаление None
значений из списка. Как правильно ее реализовать?
В подавляющем большинстве ситуаций изменение списка должно трансформироваться в создание нового списка, в котором отсутствуют удаляемые элементы. Ниже пример реализации функции compact()
def compact(coll):
# Инициализация результата
# Для пустой входной коллекции результатом будет пустой список
result = []
for item in coll:
if item is not None:
result.append(item)
return result
print(compact([0, 1, False, None, True, 'wow', None]))
# => [0, 1, False, True, 'wow']
print(compact([]))
# => []
Главное, на что здесь нужно обратить внимание - не изменяется исходный список coll
. Вместо этого создается новый список result
, который наполняется только подходящими под условие значениями.
Именно так нужно воспринимать фразу "удалить из списка что-то". Код, использующий новый список, меньше подвержен ошибкам, проще в отладке и оставляет больше возможностей для анализа. Вы всегда можете посмотреть исходный список, если что-то пошло не так. Вы всегда можете наблюдать за процессом наполнения результирующего списка, что позволит четко отследить правильность поставленных условий.
По сути, код выше — пример агрегации. Только в отличие от предыдущих примеров, в которых результатом был примитивный тип, здесь результат — список. Это совершенно нормально. Как вы увидите в дальнейшем, результат может быть и более сложной структурой. Сама операция прореживания (удаления элементов по определенным условиям) списка обычно называется фильтрацией.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.