Экспекто Питонум: 15 заклинаний на змеином языке
Короткие программы на Python — первый шаг к реальной магии кода.
![](https://248006.selcdn.ru/main/iblock/65f/65f8ad6c64c11168e9c9be3f1d1c5e71/fcee0acf8c5f5172be54783025a2cc19.png)
![](https://248006.selcdn.ru/main/iblock/65f/65f8ad6c64c11168e9c9be3f1d1c5e71/fcee0acf8c5f5172be54783025a2cc19.png)
Darshan Patel / Unsplash / Pixabay / Pexels / Colowgee для Skillbox Media
Веб-разработка и научные вычисления, роботы и Data Science — Python повсюду. На нём пишут и масштабные проекты, и короткие программы (скрипты, или сниппеты), полезные в повседневных рабочих и учебных задачах.
Собрали для вас коллекцию таких небольших «заклинаний». Основной принцип: минимум строк кода, в котором можно разобраться максимум за полминуты. Сову из Хогвартса мы не гарантируем, но удивить однокашников, коллег и интервьюеров, уверены, у вас получится. Вперёд!
Внимание: устное произнесение заклинаний в текущей версии Python не поддерживается. Вам потребуется компьютер, интерпретатор и код.
![](https://248006.selcdn.ru/main/upload/setka_images/07571802082021_accf102caaa970ce65d217b9ae9a8e9a57caa67c.jpg)
Определение строк-анаграмм — Анаграммус Ревелио
Скрипт проверяет, являются ли две строки анаграммами друг друга. Иными словами, не получена ли одна строка перестановкой символов другой строки.
from collections import Counter
def anagram(first, second):
return Counter(first) == Counter(second)
anagram("пират", "тапир")
>>> True
Используется Counter из библиотеки collections — это разновидность словаря, используемая для подсчёта элементов в итерируемых объектах: списках, кортежах, словарях, строках.
Подробнее об этой замечательной библиотеке читайте в нашей статье.
Получить размер объекта в байтах — Мемориа Байтифай
Этот скрипт используется для измерения количества памяти, потребляемой любым объектом в Python: переменной, функцией, классом.
import sys
variable = 30
print(sys.getsizeof(variable))
>>> 24
Обратите внимание, что учитывается только та память, которую занимает сам объект, а не те объекты, на которые он, возможно, ссылается. Размер памяти возвращается в байтах.
Получить длину строки в байтах — Лексиа Байтифай
Метод для определения длины строки в байтах. Это не то же самое, что размер объекта из скрипта выше.
def byte_size(string):
return(len(string.encode('utf-8')))
byte_size('Я люблю Python!')
>>> 11
print(sys.getsizeof('Я люблю Python!'))
>>> 104
byte_size('?')
>>> 4
Байтовый размер объекта-строки в памяти всегда больше байтовой длины строки, поскольку объект-строка содержит и саму строку, и дополнительную информацию о ней — например, ссылки на методы строк.
Нарезать список — Албум Диффиндо
Этот код нарезает список на списки меньшего размера, которые собраны снова в список. Размер надо задать заранее.
def chunk(list, size):
return [list[i:i+size] for i in range(0, len(list), size)]
lst = [i for i in range(25)]
chunk(lst, 7)
>>> [[0, 1, 2, 3, 4, 5, 6],
[7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24]]
Как видим, последний список получился короче: 4 элемента вместо 7. Проверьте, что будет, если размер нарезаемых списков задать больше, чем составляет длина начального списка.
В статье про списки вы узнаете чуть больше об этом полезном типе данных.
Сжать список — Албум Прессио
Этот скрипт удаляет «ложные» значения (False, None, 0 и пустую строку ' ') из списка. Используется встроенная функция filter(): c параметром None на первом месте она удалит из списка lst все значения, которые не вернут True по умолчанию.
def compact(lst):
return list(filter(None, lst))
compact([0, 1, False, None, 2, '', 3, 'a', 's', 34])
>>> [1, 2, 3, 'a', 's', 34]
Проверить вручную какое-либо значение на True/False можно с помощью функции bool(): bool(0) вернёт False, но bool('0') уже будет True, так как это непустая строка.
Примеры использования функции filter() можно найти здесь.
Транспонировать матрицу — Матрикус Транспозио
В простейшем случае двумерная матрица может быть задана списком из нескольких списков одинаковой длины, которые представляют собой строки матрицы. Если вам требуется «повернуть на 90 градусов» такую матрицу или превратить строки в столбцы (транспонировать, как говорят математики), то вот короткий код:
array = [['a', 'b'], ['c', 'd'], ['e', 'f']]
transposed = list(zip(*array))
print(transposed)
>>> [('a', 'c', 'e'), ('b', 'd', 'f')]
Обратите внимание, что в итоговом списке элементами (то есть строками новой матрицы) будут кортежи — так работает используемая здесь функция zip().
Сделать список плоским — Албум Планум
Ох уж эти списки, состоящие из списков. Как бы их сделать попроще, выстроить в один ряд? Для этого тоже есть решение.
def deep_flatten(xs):
flat_list = []
[flat_list.extend(deep_flatten(x)) for x in xs] if isinstance(xs, list) else flat_list.append(xs)
return flat_list
deep_flatten([1, [2], [[3, [1], 4], 5]])
>>> [1, 2, 3, 1, 4, 5]
В третьей строке код проверяет, не является ли элемент списком. Если да, то использует метод extend() для расширения этим элементом итогового списка, если нет — то присоединяет его как одиночный элемент методом append().
Также в этой строке функция вызывает сама себя и, в случае списков, состоящих из списков, «проваливается» в них до тех пор, пока не доберётся до элементов, не являющихся списками. Это называется рекурсией.
Проверить список на дубликаты — Дуплицио Ревелио
Этот простой скрипт проверяет, содержатся ли в списке повторяющиеся значения (дубликаты). Используется свойство множеств set, которые могут содержать только уникальные элементы.
def has_duplicates(lst):
return len(lst) != len(set(lst))
x = [1,2,3,4,5,5]
y = [1,2,3,4,5]
has_duplicates(x)
>>> True
has_duplicates(y)
>>> False
Вместо списков могут быть и кортежи, и словари. В последнем случае проверка будет выполняться только среди ключей словаря.
Объединить два словаря — Вокабулари Юнифай
Для того чтобы объединить два словаря, есть как минимум два способа: прямой и современный.
# прямой -- работает во всех версиях Python 3.*
def merge_two_dicts(a, b):
c = a.copy() # создаёт копию первого словаря
c.update(b) # обновляет копию словаря а словарём b
return c
a = { 'x': 1, 'y': 2}
b = { 'y': 3, 'z': 4}
print(merge_two_dicts(a, b))
>>> {'y': 3, 'x': 1, 'z': 4}
# современный -- работает в версиях Python 3.5 и выше
def merge_dictionaries(a, b):
return {**a, **b}
a = { 'x': 1, 'y': 2}
b = { 'y': 3, 'z': 4}
print(merge_dictionaries(a, b))
>>> {'y': 3, 'x': 1, 'z': 4}
Обратите внимание на то, что значения итогового словаря будут зависеть от порядка исходных словарей в функциях: если переставить местами словари a и b, значение ключа 'y' изменится на 2.
Найти самый частый элемент — Фрекуэнтиа
Этот короткий скрипт вернёт элемент, чаще всего встречающийся в списке.
def most_frequent(list):
return max(set(list), key = list.count)
numbers = [1,2,1,2,3,2,1,4,2]
most_frequent(numbers)
>>> 2
Используются продвинутые параметры встроенной функции max():
- первым аргументом она получает множество из элементов списка (помним, что в множестве все элементы уникальны);
- затем применяет к каждому из них функцию count, подсчитывающую, сколько раз элемент встречается в списке;
- после этого возвращает элемент множества, который имеет больше всего «попаданий».
В качестве аргумента можно использовать списки, кортежи и строки.
Проверить строку на палиндром — Палиндромус Ревелио
Простой вариант этого кода проверяет, является ли слово без пробелов и знаков препинания, написанное в одном регистре, палиндромом.
def palindrome(a):
return a == a[::-1]
palindrome('казак')
>>> True
Более сложный вариант, который сможет проверить строку «А роза упала на лапу Азора», предлагаем написать самостоятельно. Общая идея: свести сложную строку к простой, хоть и длинной 'арозаупаланалапуазора'. Вам пригодятся функции строк .lower(), .join(), а также, возможно, преобразование строки в список.
Перемешать элементы списка — Албум Миксио
Этот сниппет поможет вам изменить порядок элементов списка на случайный. Обратите внимание на то, что функция shuffle из библиотеки random меняет исходный список.
from random import shuffle
foo = [1, 2, 3, 4]
shuffle(foo)
print(foo)
>>> [3, 1, 2, 4]
Подробнее про библиотеку random и случайные числа в Python читайте в нашей статье.
Создать список дат из диапазона — Албум Датум
Этот код получает две даты (начальную и конечную) и создаёт список из дат между ними, включая начальную и исключая последнюю.
from datetime import timedelta, date
def daterange(start, end):
return [start + timedelta(n) for n in range(int((end - start).days))]
daterange(date(2020, 10, 1), date(2020, 10, 5))
>>> [datetime.date(2020, 10, 1),
datetime.date(2020, 10, 2),
datetime.date(2020, 10, 3),
datetime.date(2020, 10, 4)]
Для получения дней между начальной и конечной датой используется datetime.timedelta.days.
Получить цифры числа — Нумерум Нумерио
Превращает целое число в список его цифр.
def digitize(n):
return list(map(int, str(n)))
digitize(123)
>>> [1, 2, 3]
Функция map() принимает желаемый тип выходных данных (в нашем случае это int, целые числа) и итерируемый объект (строку, список или кортеж), элементы которого можно превратить в элементы этого типа. После этого другая функция list() преобразует результат в список.
Преобразовать арабское число в римское — Нумерум Романио
Преобразует число в обычной десятичной («арабской») записи в форму римского числа. Работает со значениями от 1 до 3999 включительно, возвращает строку (str).
def to_roman_numeral(num):
lookup = [
(1000, 'M'),
(900, 'CM'),
(500, 'D'),
(400, 'CD'),
(100, 'C'),
(90, 'XC'),
(50, 'L'),
(40, 'XL'),
(10, 'X'),
(9, 'IX'),
(5, 'V'),
(4, 'IV'),
(1, 'I'),
]
res = ''
for (n, roman) in lookup:
(d, num) = divmod(num, n)
res += roman * d
return res
to_roman_numeral(3)
>>> 'III'
to_roman_numeral(11)
>>> 'XI'
to_roman_numeral(1998)
>>> 'MCMXCVIII'
Сначала создаётся список кортежей вида (число, его римская запись). Далее цикл бежит по нему и с помощью функции divmod() производит целочисленное деление с остатком, меняя входящее число на остаток. Соответствующие результаты деления умножаются на строку римской записи и присоединяются к итоговой строке res.
Акцио Пайтон: Python в каждый дом!
Составление и изучение таких микропрограмм помогает лучше понять типы данных в Python, узнать о свойствах и параметрах функций. На сайте 30 seconds of code есть ещё больше коротких программ как для Python, так и для других языков программирования.
Источником вдохновения для названий этих скриптов послужили, конечно, книги Джоан Роулинг, а полный справочник по магическим заклинаниям мира Гарри Поттера можно посмотреть здесь.
На курсах «Профессия Python-разработчик» вы узнаете, насколько полезными могут быть такие небольшие программы, сниппеты и скрипты. Вы научитесь не только колдовать красиво решать задачи с их помощью, но и воплощать гораздо более сложные проекты. Приходите!