List Comprehension (списковые включения) в Python: примеры и лучшие практики

List Comprehension (списковые включения) в Python: примеры и лучшие практики

List Comprehension (списковые включения) в Python: примеры и лучшие практики

List comprehension (списковые включения) — это «питонический» способ создавать списки кратко и выразительно. Если вы искали «list comprehension python примеры», вы попали по адресу: разберёмся с синтаксисом, фильтрацией, вложенными циклами, dict/set comprehension, генераторами и подводными камнями. После прочтения вы будете уверенно преобразовывать данные в одну строку — без потери читаемости.

Базовый синтаксис list comprehension

Общий вид: [expression for item in iterable]. Ниже — конвертация строк в длины:

names = ['Ann', 'Bob', 'Cleo']
lengths = [len(n) for n in names]
print(lengths)  # [3, 3, 4]

Фильтрация с условием if

Добавьте условие в конец, чтобы отбирать элементы:

nums = [1, 2, 3, 4, 5, 6]
even_squares = [n*n for n in nums if n % 2 == 0]
print(even_squares)  # [4, 16, 36]

Условное выражение (if-else) внутри выражения

Важно различать фильтрацию и условный выбор значения. Если нужно вернуть разные значения — используйте тернарный оператор в expression:

temps = [-2, 0, 5]
labels = ['cold' if t <= 0 else 'warm' for t in temps]
print(labels)  # ['cold', 'cold', 'warm']

ша

Заметьте: здесь нет фильтрации — каждый элемент превращается во что-то одно.

Вложенные циклы: «разворачивание» структур

Списковые включения поддерживают несколько уровней for. Например, расплющим матрицу в один список:

matrix = [
    [1, 2, 3],
    [4, 5, 6]
]
flat = [x for row in matrix for x in row]
print(flat)  # [1, 2, 3, 4, 5, 6]

Или создадим все пары (i, j), где i != j:

items = ['a', 'b', 'c']
pairs = [(i, j) for i in items for j in items if i != j]
print(pairs)  # [('a','b'), ('a','c'), ('b','a'), ...]

Совет: если вложенность становится глубже двух уровней — чаще всего лучше переписать на обычные циклы для читаемости.

Практика: преобразование данных из файла

Считать файл, обрезать пустые строки и привести к верхнему регистру:

# data.txt:
#  alicen
#  n
#  Bobn
#  cleon

with open('data.txt', 'r', encoding='utf-8') as f:
    names = [line.strip().title() for line in f if line.strip()]
print(names)  # ['Alice', 'Bob', 'Cleo']

Dict и Set Comprehension

Те же идеи работают для словарей и множеств.

Dict comprehension

users = ['ann', 'bob', 'cleo']
name_to_len = {u: len(u) for u in users}
print(name_to_len)  # {'ann': 3, 'bob': 3, 'cleo': 4}

Set comprehension

words = ['hi', 'hi', 'hello', 'hey']
unique_lengths = {len(w) for w in words}
print(unique_lengths)  # {2, 3, 5}

Generator expression: когда список не нужен сразу

Генераторное выражение создаёт ленивую последовательность и экономит память: (expression for item in iterable).

import sys
nums = range(1_000_000)
lst = [n*n for n in nums]
gen = (n*n for n in nums)
print(sys.getsizeof(lst), 'bytes in list')
print(sys.getsizeof(gen), 'bytes in generator')
# Генератор стабильно мал по памяти, список — пропорционален размеру.

Используйте генераторы, если вы итерируетесь один раз и не нуждаетесь в случайном доступе по индексам.

Сравнение скорости: list comprehension vs цикл

Часто списковые включения работают быстрее благодаря оптимизациям CPython.

import timeit
setup = 'nums = list(range(10_000))'
stmt_loop = '''
out = []
for n in nums:
    out.append(n*n)
'''
stmt_comp = 'out = [n*n for n in nums]'
print('loop:', timeit.timeit(stmt_loop, setup=setup, number=500))
print('comp:', timeit.timeit(stmt_comp, setup=setup, number=500))
# В типичных случаях comp быстрее, но всегда замеряйте на своей задаче.

Типичные ошибки и подводные камни

  • Читаемость важнее длины. Слишком сложные вложенные включения ухудшают поддержку кода. Разбейте на шаги.
  • Побочные эффекты. Избегайте вызовов с побочными эффектами внутри expression (запись в файл, запросы в сеть). Включения — про преобразование данных, а не про действия.
  • Путаница if и if-else. [expr for x in xs if cond] фильтрует; [expr1 if cond else expr2 for x in xs] — выбирает значение для каждого элемента.
  • Переменные цикла. В Python 3 переменные из comprehension не «протекают» наружу, но не используйте одни и те же имена, чтобы избежать путаницы.
  • Размер данных. Для очень больших коллекций рассмотрите генераторы, чтобы не тратить память зря.
  • Небольшая «шпаргалка»

    # 1) Базовое преобразование
    squares = [x*x for x in xs]
    
    # 2) Фильтрация
    positives = [x for x in xs if x > 0]
    
    # 3) Условное значение
    labels = ['odd' if x % 2 else 'even' for x in xs]
    
    # 4) Вложенные циклы
    pairs = [(a, b) for a in A for b in B]
    
    # 5) Dict / Set
    index = {val: i for i, val in enumerate(xs)}
    uniq = {f(x) for x in xs}
    
    # 6) Генератор вместо списка
    g = (process(x) for x in stream)
    

    Практический мини-проект: частоты слов

    Посчитаем частоты слов в тексте: очистим, приведём к нижнему регистру, отфильтруем пустое и соберём словарь.

    text = 'Hello, hello! Is there anybody in there? Hello...'
    # Предобработка
    words = [w.strip('.,!?').lower() for w in text.split() if w.strip('.,!?')]
    # Подсчёт
    freq = {w: words.count(w) for w in set(words)}
    print(freq)  # {'hello': 3, 'is': 1, 'there': 2, 'anybody': 1, 'in': 1}
    # Для больших текстов лучше использовать collections.Counter, но идея ясна.
    

    Когда лучше НЕ использовать list comprehension

  • Сложная бизнес-логика в expression. Перенесите в именованную функцию и вызовите её из включения: [clean(x) for x in xs] — компромисс между краткостью и ясностью.
  • Требуется множественная логика ветвления и обработка исключений — лучше обычные циклы, чтобы код был очевиднее.
  • Что дальше?

    Закрепите навыки на реальных задачах: от парсинга файлов и веб-данных до мини-проектов с аналитикой. Если хотите быстро систематизировать базу и уверенно применять идиоматичный Python, загляните в курс: Пройти практический курс «Программирование на Python с Нуля до Гуру» и прокачать list comprehension на реальных проектах.

    Итоги

    List comprehension — один из ключевых инструментов «Основ Python». Освоив фильтрацию, условные выражения, вложенные циклы, а также dict/set comprehension и генераторы, вы сможете писать код короче, быстрее и понятнее. Помните про баланс между лаконичностью и читаемостью, замеряйте производительность и выбирайте инструмент по задаче — и ваш Python-код станет уровнем выше.

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий