Почему в Python не срабатывает конструкция if/else, написанная в одну строку?

Знаю, что в python есть упрощенная конструкция if/else в одну строку: (действие в случае выполнения условия) if (условие) else (действие в случае невыполнения условия). Но почему-то не могу заставить эту конструкцию работать:

for i in range(len(l)-1):
    l.pop(i) if l[i][0] in 'Мм' else pass

У меня есть список, элементы в котором являются словами (str). Мне нужно просто удалить слова, начинающиеся на букву М, т.е. элемент из списка по индексу, сам элемент мне возвращать не требуется. Самое обидное, что в развёрнутом варианте инструкция отрабатывает корректно.

for i in range(len(l)-1):
    if l[i][0] in 'Мм':
        l.pop(i)

Пробовал вместо pass писать continue, пробовал ничего не писать, ругается на синтаксис и всё тут. Хочу понять, в чём мой промах? P.S. Python 3.


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

Автор решения: Павел

Такой однострочный if называется тернарным оператором.

Используется он в основном, чтобы положить в переменную какое-то значение в зависимости от условий, но не для вызова функции, что пытаетесь сделать вы.

В принципе, с точки зрения синтаксиса так, как написали вы - писать можно (если заменить pass на None), но не нужно, потому что это примерно то же самое, что ложкой пытаться выкопать яму, логика в этом есть, но это странно, потому что l.pop(i) - это функция, которая изменяет объект, а не возвращает конкретный результат.

И обычно, когда вы делаете что-то явно не тем способом начинают возникать проблемы, как и в данном случае - это вызовет side effect, когда вы удалите первый элемент списка, то все последующие сдвинутся, и при индексации начнут пропускаться элементы и некоторые слова удовлетворяющие условию останутся в списке.

Если говорить в целом о вашей задаче:

нужно удалить слова, начинающиеся на букву М

Можно сделать гораздо проще при помощи генератора списков, это тоже удобная однострочная конструкция:

l = [x for x in l if not x.startswith(('м', 'М'))]
→ Ссылка