Решён
Что они делают, в чём их проблема? (о коде)

Григорий Фёдоров Python
282
5

Смотрю на чужой код и не могу понять логику. Вот кусок:

def process(items):
    result = []
    for i in range(len(items)):
        if items[i] != None:
            result.append(items[i])
    return result

Что они делают? В чем их проблема? Есть ли более питоничный способ написать то же самое?

Решение
55
Участник • 1 ответ

Три проблемы сразу.

Первая: items[i] != None - сравнение с None через != считается плохим тоном в Python. Правильно: is not None.

Вторая: for i in range(len(items)) - это антипаттерн. Когда нужен только элемент, не надо итерировать по индексам.

Третья: весь этот цикл заменяется одной строчкой:

result = [item for item in items if item is not None]

Или ещ... еще короче через filter:

result = list(filter(None.__ne__, items))

Хотя первый вариант читабельнее.

Аватар Григорий Фёдоров

Спасибо! Про `is not None` знал, а вот range(len()) как антипаттерн - не догадывался. Поправил.

17
Участник • 4 ответа

Вообще говоря, прежде чем писать такой код, стоит задуматься: а зачем в списке вообще появляются None? Это обычно симптом более глубокой проблемы в архитектуре. Возможно, функция, которая генерирует items, должна сама гарантировать чистые данные. Фильтрация None постфактум - это пластырь поверх пореза.

8
Участник • 1 ответ

Кстати, если хочешь убрать не только None но и пустые строки, нули и вообще все falsy значения, то просто:

result = list(filter(None, items))

Но это уже другое поведение, зависит от задачи.

8
Участник • 1 ответ

Вот это вот range(len(items)) мне в свое время объяснял препод на первом курсе. Говорил "так делать можно, но так не делают". Прошло десять лет, смотрю такой код каждую неделю на ревью. Каждую. Неделю.

Написать ответ

Премодерация гостей

Вы отвечаете как гость. Ваш ответ будет скрыт до проверки модератором. Чтобы ответ появился сразу и вы получали репутацию — войдите в аккаунт.

Будьте вежливы и соблюдайте правила платформы.