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

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

№1: Переворачивание строки

Хоть это и выглядит довольно просто, переворачивание строки с помощью литерного цикла может быть утомительным и раздражающим. К счастью, в Python есть встроенная операция для осуществления именно этой задачи — просто обращаемся к индексу ::-1 строки.

a = "!dlrow olleH"
backward = a[::-1]

№2: Dims в качестве переменных

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

firstdim = array[1]

В Python существует куда более классный и быстрый способ: чтобы превратить список значений в переменные, просто задайте имена переменных равными массиву той же длины:

array = [5, 10, 15, 20]
five, ten, fift, twent = array

№3: Модуль itertools

Если вы собираетесь посвятить некоторое время работе с Python, вам наверняка захочется освоить itertools. Itertools — это модуль стандартной библиотеки, позволяющий постоянно работать с итераторами. Он не только намного упрощает код сложных циклов, но и делает код быстрее и лаконичнее. Вот только один пример использования Itertools, на самом деле их сотни:

c = [[1, 2], [3, 4], [5, 6]]
# Давайте преобразуем эту матрицу в одномерный список
import itertools as it
newlist = list(it.chain.from_iterable(c))

№4: Умная распаковка

Итеративная распаковка значений может быть довольно трудоёмкой и времязатратной. К счастью, у Python есть несколько замечательных способов распаковки списков! Одним из них является звездочка (*), заполняющая не определённые значения и добавляющая их к списку под именем переменной.

a, *b, c = [1, 2, 3, 4, 5]

№5: Enumerate

Если вы не знакомы с enumerate, настоятельно рекомендую освоить его. Enumerate позволяет получать индексы заданных значений в списке, что особенно полезно в науке о данных при работе с массивами, а не фреймами данных:

for i,w in enumerate(array):
    print(i,w)

№6: Именование секторов

Нарезать списки на сектора в Python невероятно просто! Для этого существует множество отличных инструментов, но один из самых ценных, это возможность именовать сектора списка, что особенно полезно в линейной алгебре в Python:

a = [0, 1, 2, 3, 4, 5]
LASTTHREE = slice(-3, None)
slice(-3, None, None)
print(a[LASTTHREE])

№7: Группировка смежных списков

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

a = [1, 2, 3, 4, 5, 6]  
group_adjacent = lambda a, k: zip(*([iter(a)] * k)) 
group_adjacent(a, 3) [(1, 2, 3), (4, 5, 6)] 
group_adjacent(a, 2) [(1, 2), (3, 4), (5, 6)] 
group_adjacent(a, 1)

№8: Итерация next() для генераторов 

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

array1 = [5, 10, 15, 20]
array2 = (x ** 2 for x in range(10))
counter = 0for i in array1:

# Этот код не будет работать, потому что 'i' нет в array2.
   # i = array2[i]
    i = array2[counter]
#  ^^^ Этот код заработает, потому что мы получим доступ к позиции i

Однако вместо этого можно использовать next(). Next берёт итератор, который будет хранить текущую позицию в памяти и перебирать список в фоновом режиме.

g = (x ** 2 for x in range(10))
print(next(g))
print(next(g))

№9: Counter

Ещё один прекрасный модуль из стандартной библиотеки — collections, и я хотел бы познакомить вас с collections.Counter. Используя Counter, легко получить счётчик списка. Это полезно для получения общего количества значений в данных, нулевого счёта данных и просмотра уникальных значений. Я знаю, вы подумали:

“ Почему бы просто не использовать Pandas?”

И это, безусловно, весомый аргумент. Однако Pandas для этих целей довольно сложно автоматизировать. Кроме того, это будет ещё одна зависимость, которую придётся добавлять в виртуальную среду при каждом развёртывании алгоритма. В counter есть множество функций, которых нет в Pandas Series, что делает его значительно полезнее в определённых ситуациях:

A = collections.Counter([1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 6, 7]) 
A Counter({3: 4, 1: 2, 2: 2, 4: 1, 5: 1, 6: 1, 7: 1}) 
A.most_common(1) [(3, 4)] 
A.most_common(3) [(3, 4), (1, 2), (2, 2)]

№10: Исключение из очереди

Ещё один прекрасный тип из модуля collections — это dequeue. Взгляните!

import collections
Q = collections.deque() 
Q.append(1) 
Q.appendleft(2) 
Q.extend([3, 4]) 
Q.extendleft([5, 6]) 
Q.pop()
Q.popleft()
Q.rotate(3) 
Q.rotate(-3)
print(Q)

Вывод

Я рассказал о некоторых излюбленных приёмах, которые постоянно использую. Хотя некоторые из них применимы довольно редко, они универсальны и полезны. К счастью, набор инструментов стандартной библиотеки Python не оскудевает, внутри него можно найти множество замечательных функций, поэтому всегда есть, чему поучиться!

Читайте также:


Перевод статьи Emmett Boudreau: 10 Smooth Python Tricks For Python Gods

Предыдущая статьяЛучшие практики и инструменты для микрофронтендов
Следующая статьяПрограммное обеспечение без конструкции if-else