Добавить в корзинуПозвонить
Найти в Дзене
Удалёнка

Приемы Python, которым редко учат начинающих

Python сейчас — самый используемый язык программирования в мире. А причина этого в том, что разработчикам нравится создавать программы на этом языке. У него простой синтаксис, широкое разнообразие библиотек, да и изучить этот язык можно довольно быстро. Все это подкупает как новичков, так и опытных программистов. А еще, как и в любом языке, в Python есть целый ряд тонкостей и приемов, о которых редко рассказывают. Давайте рассмотрим некоторые из них. Выбор случайного элемента из последовательности Пакет random из стандартной библиотеки Python имеет много полезных функций. Но одна выделяется на общем фоне — random.choice(seq). Эта функция позволяет вам выбирать случайный элемент из индексируемой последовательности, например, из списка, кортежа или даже из строки. import random as r my_list = [1, 2, 3, "go"] print(r.choice(my_list)) # Случайный элемент Применение на практике Можно создать функцию для выбора книги. Она будет получать последовательность из книг, выбирать одну из них случай

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

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

А еще, как и в любом языке, в Python есть целый ряд тонкостей и приемов, о которых редко рассказывают. Давайте рассмотрим некоторые из них.

Выбор случайного элемента из последовательности

Пакет random из стандартной библиотеки Python имеет много полезных функций. Но одна выделяется на общем фоне — random.choice(seq).

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

import random as r

my_list = [1, 2, 3, "go"]

print(r.choice(my_list))

# Случайный элемент

Применение на практике

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

# Импортируем только нужную нам функцию

from random import choice

def book_picker(books):

book_choice = choice(books)

books.remove(book_choice)

return f"You picked {book_choice}"

books = ["Harry Potter", "Don Quixote", "Frankenstein", "Dracula"]

print(book_picker(books)) # Случайный выбор

print(books) # Оставшиеся книги

Ограничения и исключения

Если вы попытаетесь использовать random.choice(seq) для неиндексируемой последовательности, например, для словаря, множества или числовых типов, Python выдаст ошибку.

# Со словарем

import random as r

scores = {"Jhon": 4, "Ben": 3, "Diana": 5}

print(r.choice(my_scores)) # Key error

А если последовательность будет пустой, вы получите IndexError.

# С пустой последовательностью

import random as r

empty_list = []

print(r.choice(empty_list)) # Index error

Распаковка элементов при помощи *

Бывает, нужно вывести элементы итерируемого объекта так, чтобы их разделяли пробелы. Обычно применяется следующее решение:

my_list = [1, 2, 3, 5, 7]

for i in my_list:

print(i, end=" ") # 1 2 3 5 7

И хотя этот код решает задачу, он не слишком питоничный. Есть более простое и элегантное решение — с использованием оператора распаковки *.

my_list = [1, 2, 3, 5, 7]

print(*my_list) # 1 2 3 5 7

Как видите, оператор распаковки всегда ставится слева от итерируемого объекта. Он как бы говорит Python: «Помести каждый элемент этого итерируемого объекта в желаемый список или кортеж».

Не забывайте, что итерируемый объект — это любая последовательность, которую мы можем проитерировать в цикле for. Если вы хотите проверить, является ли какой-нибудь тип данных итерируемым, используйте функцию iter().

print(iter("This is a string")) # Str Iterable object

print(iter(["this", "is", "a", "list"])) # List iterable object

print(iter(1))

# Выбрасывается ошибка

# Числа нельзя итерировать

Использование распаковки с переменными

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

string = "Let's learn Python"

# Мы хотим назначить результат распаковки как значение var1

var1 = [*string]

print(var1)

# ['L', 'e', 't', "'", 's', ' ', 'l', 'e', 'a', 'r', 'n', ' ', 'P', 'y', 't', 'h', 'o', 'n']

Часть [*итерируемый_объект] может показаться непонятной, так что давайте разберемся.

Когда мы распаковываем итерируемый объект, Python нужна какая-нибудь структура данных для сохранения элементов этого объекта. Поэтому мы создаем список ([]), захватывая в него и оператор *.

Если мы захотим узнать тип результирующей переменной, мы получим:

another_str = "The * operator"

# Помещаем распаковку в список

var2 = [*another_str]

print(type(var2)) # Список

# Используем кортеж

# Кортежи заканчиваются запятой

var3 = (*another_str,)

print(type(var3)) # Кортеж

И естественно, если вы попытаетесь назначить в качестве значения переменной распаковку объекта без создания списка или кортежа, вы получите SyntaxError:

bad_variable = *"Bad String"

# Syntax error

python logo

Еще один пример использования распаковки

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

some_iterable = ["I", "have", "no", "idea", "how", "many", "values", "are", "here", "so", "this", "will", "be", "fun!"]

first, second, *_, last = *some_iterable

print(first, second, last) # I have fun!

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

print(_) # ['no', 'idea', 'how', 'many', 'values', 'are', 'here', 'so', 'this', 'will', 'be']

Вообще, распаковка — очень полезная вещь, имеющая множество вариантов применения.

Использование set для оптимизации операторов

Согласно документации Python, класс set(iterable) создает объект множества из итерируемого объекта.

Как многие из вас знают, множество — это неупорядоченная структура данных (а значит, и неиндексируемая). Одна из отличительных черт множества — в нем не может быть дубликатов элементов.

Практический пример

Функция, удаляющая дубликаты и возвращающая отсортированный список:

def eliminate_duplicates(lst):

"""

Возвращает отсортированный список без дубликатов

"""

new_list = list(set(lst))

new_list.sort()

return new_list

list1 = [25, 12, 11, 4, 12, 12, 25]

print(eliminate_duplicates(list1))

Просмотр атрибутов и методов класса без выхода из редактора

Функция dir() возвращает атрибуты и методы класса. Мы можем использовать ее, чтобы составить список всех определений внутри класса.

-> $ python

string = "A string"

print(dir(string))

# ['__add__', .....,'upper', 'zfill']

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

Практический пример

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

-> $ python

from django.views import View

print(dir(View))

# ['__class__', '__delattr__', .... 'setup']

Операции срезов

Срез — это не что иное, как способ обратиться к определенной части последовательности. В Python срезы позволяют нам проделывать различные трюки.

Разворот последовательности

# Разворот списков

lst = ["Fun", "is", "Programming"]

lst = lst[::-1]

print(lst) # ['Programming', 'is', 'Fun']

# Разворот строк

string = "Dog running on the park"

string = string[::-1]

print(string) # krap eht no gninnur goD

Практический пример

Функция, возвращающая последовательность до заданного индекса:

def cutoff(seq, index):

if not len(seq) > index:

return "Sorry the index is bigger than the sequence"

return seq[:index]

long_string = "This is a long description of a blog post about Python and technology"

print(cutoff(long_string, 15))

# This is a long

print(cutoff(long_string, 70))

# Sorry the index is bigger than the sequence

Введите 10 букв — и вызовите дебаггер

Функция breakpoint доступна в Python, начиная с версии 3.6. Она вызывает сессию pdb.set_trace().

Пример

n_odds = 0

for i in range(1, 14, 2):

# Проверка значения i в каждой итерации

breakpoint()

# Плохое условие

if i % 2 == 0:

n_odds += 1

print(n_odds)

Скриншот терминала, показано использование функции breakpoint

Может показаться, что это так себе удобство, но это быстрый способ вызвать отладчик.

Итоги

Прочитав эту статью, вы научились:

  • выбирать рандомный элемент из последовательности
  • распаковывать элементы при помощи оператора *
  • эффективно удалять дубликаты при помощи множеств
  • искать методы и переменные, не покидая редактор кода
  • использовать срезы разными способами
  • вызывать отладчик при помощи функции breakpoint.