← Все вопросы

Как отфильтровать список по условию в Python?

Задан 8 месяцев назад277 просмотров2 ответа
10

Есть список чисел, хочу оставить только те, что больше нуля (или только чётные). Делаю через цикл с if и append в новый список, но кажется, что должно быть короче. Как фильтровать список по условию?

2 ответа

15
✓ Принятый ответ — помог автору

Самый питоничный способ — списочное включение (list comprehension) с условием if в конце:

nums = [-2, 5, -1, 8, 0, 3]

positive = [x for x in nums if x > 0]   # [5, 8, 3]
evens = [x for x in nums if x % 2 == 0] # [-2, 8, 0]

Читается слева направо: «возьми x из nums, если выполняется условие». Это короче и быстрее, чем цикл с append.

Можно сразу и преобразовывать элемент, и фильтровать:

# квадраты только положительных
[x**2 for x in nums if x > 0]   # [25, 64, 9]

Альтернатива — встроенная filter():

positive = list(filter(lambda x: x > 0, nums))

Но filter возвращает ленивый объект, его надо оборачивать в list(), и lambda многословнее. В современном Python списочное включение обычно предпочтительнее.

Важно про порядок if и for:

  • Условие-фильтр ставится после for: [x for x in nums if x > 0].
  • А вот тернарное условие (когда нужно заменять значение, а не отбрасывать) ставится перед for: [x if x > 0 else 0 for x in nums].

Это разные конструкции, их часто путают: первая выкидывает элементы, вторая оставляет все, но меняет.

4

Если условий несколько, их можно объединять через and/or:

[x for x in nums if x > 0 and x % 2 == 0]   # положительные И чётные

А для фильтрации списка словарей условие просто обращается к ключу:

adults = [p for p in people if p['age'] >= 18]

Когда условие становится сложным, вынесите его в отдельную функцию def is_ok(x): ... и пишите [x for x in nums if is_ok(x)] — так читаемее, чем громоздкое выражение в скобках.

Ваш ответ

Войдите, чтобы ответить на вопрос.