eFusion 30 декабря 2019
2
4871

5 полезных фич Python, о которых знают не все

Python – один из самых популярных и мощных ЯП, скрывающих массу полезностей и фич. Пять из них мы осветили в статье.

Даже если ты программист, перешедший с других языков, таких как C, в программирование на Python с более высоким уровнем абстракции – не стоит пугаться и отступать перед “не таким” кодом. Погнали!

List comprehensions – компактный код

Многие назвали бы lambda, map и filter "трюками" Python, которым должен научиться каждый новичок. Принято считать, что эти функции большую часть времени, не особенно полезны, поскольку им не хватает гибкости.

Лямбда – это метод составления функции в одну строку для одноразового использования. Если он вызывается несколько раз, страдает производительность. С другой стороны, map применяет функцию ко всем элементам списка, в то время как filter получает подмножество элементов в наборе, удовлетворяющем пользовательскому условию.

            add_func = lambda z: z ** 2
is_odd = lambda z: z%2 == 1
multiply = lambda x,y: x*y

aList = list(range(10))
print(aList)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        

List comprehensions – это лаконичный метод для создания списков из других списков с гибкими выражениями и условиями. Он выделяется квадратными скобками, в которых определено выражение или функция. Когда элемент удовлетворяет условию, только в этом случае действие применяется к каждому элементу списка. Метод также может обрабатывать вложенные списки продуктивнее, чем использование мапы и фильтра.

            # Syntax of list comprehension
[ expression(x) for x in aList if optional_condition(x) ]
        
            print(list(map(add_func, aList)))
print([x ** 2 for x in aList])
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

print(list(filter(is_odd, aList)))
print([x for x in aList if x%2 == 1])
# [1, 3, 5, 7, 9]
# [1, 3, 5, 7, 9]
        

Манипуляции со списками – циклические списки

Python поддерживает отрицательную индексацию, где aList[-1] == aList[len(aList)-1]. Исходя из этого, можно получить второй последний элемент в списке – aList[-2] и так далее.

Также можно нарезать списки с помощью записи aList[start:end: step], где начальный элемент указан, а конечный – нет. Поэтому вызов aList[2:5] вернет [2, 3, 4], а вызвав aList[:: -1], ты сможешь переставить элементы в списке в обратном порядке – очень элегантная техника.

А еще списки могут быть распакованы в отдельные элементы или сливать элементы, которые не влезли в лимит переменных, в подсписок, используя звездочку.

            a, b, c, d = aList[0:4]
print(f'a = {a}, b = {b}, c = {c}, d = {d}')
# a = 0, b = 1, c = 2, d = 3

a, *b, c, d = aList
print(f'a = {a}, b = {b}, c = {c}, d = {d}')
# a = 0, b = [1, 2, 3, 4, 5, 6, 7], c = 8, d = 9
        

zip, enumerate и for-loops

Функция zip создает итератор, который агрегирует элементы из нескольких списков. Он позволяет выполнять параллельный обход списков в цикле for и параллельную сортировку. Обратное действие (unzip) совершается с помощью звездочки.

            numList = [0, 1, 2]
engList = ['zero', 'one', 'two']
espList = ['cero', 'uno', 'dos']
print(list(zip(numList, engList, espList)))
# [(0, 'zero', 'cero'), (1, 'one', 'uno'), (2, 'two', 'dos')]

for num, eng, esp in zip(numList, engList, espList):
    print(f'{num} is {eng} in English and {esp} in Spanish.')
# 0 is zero in English and cero in Spanish.
# 1 is one in English and uno in Spanish.
# 2 is two in English and dos in Spanish.
        
            Eng = list(zip(engList, espList, numList))
Eng.sort() # sort by engList
a, b, c = zip(*Eng)

print(a)
print(b)
print(c)
# ('one', 'two', 'zero')
# ('uno', 'dos', 'cero')
# (1, 2, 0)
        

enumerate может показаться немного пугающим, но данную функцию удобно применять во многих ситуациях. Наиболее популярный вариант – автоматический счетчик для цикла for: больше нет необходимости создавать и инициализировать переменную счетчика с помощью counter = 0 и counter += 1. enumerate и zip – это два самых мощных инструмента при построении цикла for.

            upperCase = ['A', 'B', 'C', 'D', 'E', 'F']
lowerCase = ['a', 'b', 'c', 'd', 'e', 'f']
for i, (upper, lower) in enumerate(zip(upperCase, lowerCase), 1):
    print(f'{i}: {upper} and {lower}.')
# 1: A and a.
# 2: B and b.
# 3: C and c.
# 4: D and d.
# 5: E and e.
# 6: F and f.
        

Генератор – эффективность использования памяти

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

Они часто используются при чтении больших файлов или создании бесконечной последовательности при помощи ключевого слова yield.

            def gen(n):    # an infinite sequence generator that generates integers >= n
    while True:
        yield n
        n += 1
        
G = gen(3)     # starts at 3
print(next(G)) # 3
print(next(G)) # 4
print(next(G)) # 5
print(next(G)) # 6
        

Виртуальная среда – изоляция

Самая интересная и увлекательная штука из подборки.

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

            conda create -n venv pip python=3.7  # select python version
source activate venv
...
source deactivate
        

Поэтому крайне важно создать отдельные автономные виртуальные среды venv для каждого приложения, что и можно сделать с помощью pip или conda.

А какие фичи в Python любишь ты?

Источники

РУБРИКИ В СТАТЬЕ

МЕРОПРИЯТИЯ

Митап Experiment Fest x Яндекс.Практикум
16 февраля Москва Бесплатно
Митап по удаленной работе в IT - Зимний Remote Camp
25 января Санкт-Петербург Бесплатно
Вебинар «Ключевые аспекты безопасности Облака»
23 января Москва Онлайн Бесплатно
С++ meetup Moscow #5 in Align Technology
23 января Москва Бесплатно

Комментарии 2

ВАКАНСИИ

Senior / Lead Game Analyst
по итогам собеседования
Machine Learning Software Engineer
Париж, по итогам собеседования
Разработчик Unity 3D
Новосибирск, по итогам собеседования
Unity Developer
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

BUG