Как удалить элементы "Нет" из конца списка в Python
Есть список, который может содержать элементы, которых нет. Я хотел бы удалить эти элементы, но только если они появляются в конце списка, поэтому:
[None, "Hello", None, "World", None, None]
# Would become:
[None, "Hello", None, "World"]
Я написал функцию, но я не уверен, что это правильный путь в Python?:
def shrink(lst):
# Start from the end of the list.
i = len(lst) -1
while i >= 0:
if lst[i] is None:
# Remove the item if it is None.
lst.pop(i)
else:
# We want to preserve 'None' items in the middle of the list, so stop as soon as we hit something not None.
break
# Move through the list backwards.
i -= 1
Также в качестве альтернативы можно использовать понимание списка, но это кажется неэффективным и не более читабельным?:
myList = [x for index, x in enumerate(myList) if x is not None or myList[index +1:] != [None] * (len(myList[index +1:]))]
Какой это питонский способ удалить элементы, которые "Нет", из конца списка?
Ответы
Ответ 1
Сброс с конца списка эффективен.
while lst[-1] is None:
del lst[-1]
При необходимости добавьте защиту для IndexError: pop from empty list
. От вашего конкретного приложения зависит, следует ли считать обработку пустого списка нормальной или ошибочной.
while lst and lst[-1] is None:
del lst[-1]
Ответ 2
Если вы не хотите изменять список, вы можете просто найти первый индекс справа, который не является None, и нарезать его:
def shrink(l):
for i in range(len(l) - 1, -1, -1):
if l[i] is not None:
return l[:i + 1]
return l[:0]
Если вы хотите изменить список на месте, вы можете просто удалить срез:
def shrink(l):
for i in range(len(l) - 1, -1, -1):
if l[i] is not None:
break
else:
i = -1
del l[i + 1:]
Ответ 3
Самый простой способ - это то, что ты сделал. Вот концептуально более простая реализация этого:
def shrink(lst):
copy_lst = lst[:] # don't modify the original
while copy_lst[-1] is None: # you can get the last element in 1 step with index -1
copy_list.pop()
return copy_lst
Начиная с python 3.8 и оператора моржа, это можно было бы сделать с помощью понимания списка, но это хакерское решение, и вы не должны его использовать:
def shrink(lst):
at_end = True
return reversed([(at_end := e is None and at_end, e)[1] for e in reversed(lst) if not at_end])