Удаление элементов списка по условию

Из списка чисел удалить элементы, значения которых принадлежат определенному диапазону (например, больше 35-ти и меньше 65-ти). Удаляемые значения сохранить в другом списке.

Решение задачи на языке программирования Python

Алгоритм решения задачи выглядит простым. Достаточно перебрать элементы списка и удалить те, которые удовлетворяют условию. Однако при удалении элемента на его место становится следующий, но поскольку мы переходим к следующей ячейке, то пропускаем проверку того, что стал на место удаленного. Таким образом, цикл for, в теле которого перебираются элементы, использовать нельзя, так как меняется количество элементов списка.

a = [96, 72, 44, 29, 97, 69, 25, 12]
print("A =", a)

b = []

for i in a:
    if 20 < i < 90:
        a.remove(i)
        b.append(i)

print("A =", a)
print("B =", b)

Результат:

A = [96, 72, 44, 29, 97, 69, 25, 12]
A = [96, 44, 97, 25, 12]
B = [72, 29, 69]

В примере число 44 оказалось пропущенным, так как когда было удалено 72, то 44 стало на его место. На следующей итерации цикла проверялось содержимое третьей ячейки, в которой уже стояло число 29. То же самое касается числа 25, перед которым было удалено 69.

По всей видимости перебирать следует не сами элементы списка, а их индексы. В этом случае для удаления элементом не совсем подходит метод remove(), которому передается значение. В Python удалять элементы списка по индексу можно инструкцией del, при которой указывается сам список и индекс удаляемого элемента.

Также будем использовать цикл while, в теле которого уменьшать длину списка, если элемент был удален, или увеличивать индекс (переходить к следующей ячейке списка), если удаления элемента не произошло.

import random

a = []
for i in range(10):
    n = round(random.random() * 100)
    a.append(n)
print("A =", a)

b = []
i = 0
length = len(a)
while i < length:
    if 35 < a[i] < 65:
        b.append(a[i])
        del a[i]
        length = length - 1
    else:
        i += 1

print("A =", a)
print("B =", b)

Примеры выполнения программы:

A = [66, 57, 72, 65, 37, 67, 23, 16, 30, 72]
A = [66, 72, 65, 67, 23, 16, 30, 72]
B = [57, 37]
A = [1, 65, 85, 62, 2, 1, 52, 63, 36, 94]
A = [1, 65, 85, 2, 1, 94]
B = [62, 52, 63, 36]

Более оригинальным способом решения задачи является перебор элементов списка с конца. В этом случае индекс меняется от большего к меньшему. При этом если происходит удаление элемента и сокращение длины списка, это не оказывает никакого влияния на элементы (их индексы), стоящие до удаляемого значения.

from random import randint

a = [randint(0, 99) for j in range(10)]
print("A =", a)

b = []
i = len(a) - 1
while i >= 0:
    if 35 < a[i] < 65:
        b.insert(0, a.pop(i))
    i -= 1

print("A =", a)
print("B =", b)

Здесь вместо метода append() используется insert(), чтобы элементы во втором списке шли в том же порядке, в котором они были в первом, а не задом наперед.

Также в этом примере решения задачи показано использование спискового метода pop(), который удаляет элемент по индексу, если таковой передается. Выражение a.pop(i) аналогично del a[i] за тем исключением, что в метод возвращает удаленное значение, а оператор del - нет.

В случае перебора с конца также можно использовать цикл for, если знать о том, что с помощью функции range() можно создавать диапазоны от большего числа к меньшему.

from random import randint

a = [randint(0, 99) for j in range(10)]
print("A =", a)

b = []

for i in range(len(a)-1, -1, -1):
    if 35 < a[i] < 65:
        b.insert(0, a.pop(i))

print("A =", a)
print("B =", b)

Выражение range(len(a)-1, -1, -1) при длине списка a в 10 элементов означает, что будет получен диапазон, первый элемент которого 9, последний 0 (значение -1 в диапазон не входит). Третий аргумент в функции range() является шагом, то есть здесь следующий элемент получается из предыдущего вычитаем единицы.


Решение задач на Python




Все разделы сайта