Когда я только начинала программировать на Python, меня поражала простота и элегантность языка. Но со временем я обнаружила, что Python скрывает в себе гораздо больше, чем кажется на первый взгляд. Есть множество небольших, но очень мощных трюков, которые могут значительно облегчить жизнь программисту и сделать код не только более лаконичным, но и более эффективным.

Сегодня я хочу поделиться с вами пятью такими трюками, которые выведут ваши навыки на новый уровень. Погнали!

1. Лямбда-функции: компактные и удобные

Я обожаю лямбда-функции за их краткость. Они идеальны, когда нужно написать маленькую функцию прямо в строке кода и не засорять пространство имен лишними определениями.

Например, вот так выглядит обычная функция для умножения двух чисел:

def multiply(x, y):
    return x * y

А вот так же самое, только с лямбдой:

multiply = lambda x, y: x * y

Зачем использовать лямбда-функции? Они отлично подходят, когда нужно передать простую функцию внутрь другой функции. Вот пример сортировки списка словарей по возрасту:

people = [{'name': 'Алиса', 'age': 30}, {'name': 'Боб', 'age': 25}, {'name': 'Чарли', 'age': 35}]

# Сортируем по возрасту
sorted_people = sorted(people, key=lambda person: person['age'])

print(sorted_people)

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

2. Генераторы: работа с большими данными без лишней нагрузки

Генераторы — это просто находка, когда нужно обрабатывать большие объёмы данных. Особенно если данные приходят постепенно, и загружать их все в память просто неразумно.

Когда я работаю с большими файлами, вместо того чтобы читать весь файл разом, я использую генератор для построчной обработки. Это не только экономит память, но и позволяет работать с данными более эффективно.

Вот пример, как можно построчно читать огромный файл:

def read_large_file(file_path):
    with open(file_path) as file:
        for line in file:
            yield line.strip()  # Используем yield, чтобы возвращать строки по одной

# Используем генератор
for line in read_large_file('huge_file.txt'):
    print(line)

Когда файл весит несколько гигабайт, это спасает. Так как строки не загружаются все сразу, а генерируются по мере необходимости, память используется очень бережно.

3. Декораторы: добавляем функциональность, не трогая код

Декораторы — это один из тех инструментов, которые я недооценивала, когда только начала изучать Python. Теперь я постоянно использую их, когда нужно добавить повторяющуюся логику в функции, не изменяя саму функцию.

Например, я часто хочу видеть, сколько времени выполняется та или иная функция. Вместо того чтобы встраивать измерение времени в каждую функцию вручную, я могу создать декоратор:

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Функция {func.__name__} выполнилась за {end_time - start_time:.4f} секунд")
        return result
    return wrapper

Теперь я могу просто добавить этот декоратор к любой функции:

@timer
def slow_function():
    time.sleep(2)
    print("Функция завершена")

slow_function()

Запускаю функцию — и сразу вижу, сколько времени она заняла. Это очень удобно, особенно при оптимизации кода.

4. Использование collections для более удобных структур данных

Когда мне нужно что-то более сложное, чем обычные списки или словари, я часто использую модуль collections. Это потрясающая библиотека, которая предоставляет более мощные и гибкие структуры данных.

Например, defaultdict — это словарь с предустановленным значением по умолчанию. Однажды у меня была задача подсчитать, сколько раз встречается каждое слово в тексте. В стандартном словаре для этого пришлось бы проверять, есть ли ключ уже, и если нет — добавлять его. А с defaultdict это делается проще:

from collections import defaultdict

text = "это пример текста, это всего лишь пример"
word_count = defaultdict(int)

for word in text.split():
    word_count[word] += 1

print(word_count)

Каждый раз, когда встречается новое слово, оно автоматически добавляется в словарь с начальным значением 0, а потом просто увеличивается на единицу. Это сильно упрощает код, и мне не нужно беспокоиться о проверках.

5. Списковые включения: пишем меньше, делаем больше

И наконец, списковые включения (list comprehensions) — это моя любовь. Они позволяют записывать целые циклы в одну строку и при этом делают код более читаемым.

Вот пример, когда мне нужно создать список квадратов всех чисел от 0 до 9:

squares = [x**2 for x in range(10)]
print(squares)

Без списковых включений пришлось бы писать более громоздкий код:

squares = []
for x in range(10):
    squares.append(x**2)

Вроде бы небольшое изменение, но когда такие конструкции встречаются часто, начинаешь по-настоящему ценить лаконичность Python.

Заключение

Эти трюки стали для меня настоящими помощниками в повседневной работе. В них нет ничего сверхсложного, но каждый из них может значительно облегчить жизнь программисту. Попробуйте внедрить их в свой код, и вы сразу почувствуете разницу.

Комментарии (12)


  1. NekkittAY
    24.09.2024 20:30
    +4

    "Трюки" на уровне быстрых вопросов к джуну на собесе. Куда полезнее было бы рассмотреть реализацию структур данных на низком уровне в CPython для понимания их работы и эффективности применения в конкретных случаях. Если допустить к рассмотрению библиотеки, то тут ещё больше полезной информации можно было собрать: оптимизация вычислений (NumPy для матриц, массивов, линейной алгебры; Numba для jit-компиляции, распараллеливания циклов (тут ещё joblib подойдёт) и кэширования; CuPy для numpy/scipy кода под GPU), работа с памятью и так далее. В общем, статья для только-только начинающих изучать Python, а о мастере кодинга с этими знаниями можно говорить только в качестве насмешки.


    1. VolkaMaria Автор
      24.09.2024 20:30

      Вы правы, эти трюки скорее для тех, кто только начинает осваивать Python. Более глубокие темы, такие как внутренняя реализация структур данных, оптимизация с использованием NumPy, Numba и других библиотек, безусловно, намного полезнее для тех, кто хочет реально прокачать свои навыки. В дальнейшем, буду рада копнуть в эту сторону!


      1. Lis777
        24.09.2024 20:30

        Хорошо кому-то она может копать в стороны.)) А я только зарегистрировалась я даже спросить ничего не могу, нет прав. )) Numba для jit-компиляции, CuPy и  joblib еще не изучала, Все еще впереди. А описанная выше статья вполне закрепляет ранее пройденный материал, лично мне полезно.


        1. NekkittAY
          24.09.2024 20:30
          +3

          Насчет полезности не спорю, но громкое название статьи относительно содержимого меня несколько раздосадовало, естественно на "сакральные знания" не надеялся, но простор для темы куда больше. К примеру, описать архитектурные паттерны и паттерны проектирования на Python (по возможности применения, все же ООП на Python отдельный вопрос), это уже достаточно сильный уровень для dev'а будет.


          1. Lis777
            24.09.2024 20:30

            Это один из методов сетевого маркетинга. И он сработал)) Мы же зашли, прочитали и прокомментировали. А ожидания у всех разные, да и в целом в жизни ожидания и реальность мало когда совпадают.


            1. shaggyone
              24.09.2024 20:30

              Да да, не газ пришел, если вы видите эту рекламу зависит она работает. Вероятно этого хватает для обмана рекламодателей.


  1. ibreeed
    24.09.2024 20:30
    +13

    Однажды у меня была задача подсчитать, сколько раз встречается каждое слово в тексте. В стандартном словаре для этого пришлось бы проверять, есть ли ключ уже, и если нет — добавлять его. А с defaultdict это делается проще

    Для решения данной задачи в collections есть более подходящий инструмент Counter:

    from collections import Counter
    
    text = "это пример текста, это всего лишь пример"
    Counter(text.split())
    # Counter({'это': 2, 'пример': 2, 'текста,': 1, 'всего': 1, 'лишь': 1})


  1. Tanner
    24.09.2024 20:30

    Именовать лямбды нехорошо.


    1. JastixXXX
      24.09.2024 20:30

      А не могли бы вы уточнить, почему?


      1. baldr
        24.09.2024 20:30

        1. JastixXXX
          24.09.2024 20:30

          Спасибо. Я похоже читаю через одно место сегодня, ибо у меня прочиталось "использовать лямбды не хорошо" :)


  1. eulampius
    24.09.2024 20:30

    Когда я только начинала программировать на Python, меня поражала простота и элегантность языка. Но со временем я обнаружила...

    Декораторы, генераторы, некоторые коллекции, списковые выражения, лямбды.

    Если вот это "со временем" уложилось в одну, максимум, две недели, то вы неплохо продвигаетесь )