4 полезных приема работы с Python

Перевод статьи «4 Ways To Level Up Your Python Code».

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

Один из плюсов Python — с его помощью можно заставить работать что угодно. 

Еще один плюс — множество скрытых фишек, которые не только облегчают написание кода, но и делают код «чище» и удобнее для чтения.

В этой статье мы разберем фишки, которые помогут вам отточить ваши навыки. 

1. Забудьте о range(len()). Наш выбор — enumerate() 

Часто возникают ситуации, когда нужно перебрать коллекцию и отслеживать индексы элементов, к которым вы получили доступ. Для этих целей многие использует range(len(коллекция)).

Функция enumerate возвращает enumerate-объект, который хранит в себе и индексы элементов, и их значения. 

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

Рассмотрим пример, в котором видна разница между range(len(коллекция)) и enumerate(коллекция).

# объявляем коллекцию — список:
names = ['Никита', 'Дарья', 'Екатерина', 'Дмитрий', 'Владимир']

# в случае с range(len(collection)) вы бы написали:
for i in range(len(names)):
    print(i, names[i])

# в случае с enumerate вы бы написали:
for idx, name in enumerate(names):
    print(idx, name)

# Оба варианта возвращают:
# 0 Никита
# 1 Дарья
# 2 Екатерина
# 3 Дмитрий
# 4 Владимир

Еще одна полезная особенность enumerate — можно начинать отсчет не с 0. Для этого вам нужно лишь добавить параметр — start=параметр. Предположим, мы хотим начать выводить элементы списка с 1.

# объявляем коллекцию — список:
names = ['Никита', 'Дарья', 'Екатерина', 'Дмитрий', 'Владимир']

# при использовании enumerate перебор с 1 реализуется так:
for idx, name in enumerate(names, start=1):
    print(idx, name)

# Цикл вернет:
# 1 Никита
# 2 Дарья
# 3 Екатерина
# 4 Дмитрий
# 5 Владимир

2. Забудьте о квадратных скобках — получайте элементы словаря с помощью .get()

Допустим, мы объявили словарь:

nikita = {
  'возраст':32,
  'пол':'мужской',
  'трудоустроен':True,
}

И хотим получить значение возраст. Возможно, вы уже привыкли использовать в таких случаях nikita['возраст']. В нашем примере это сработает, но если значения не существует, — нет. 

Например, при попытке получить доступ к несуществующему значению 'место жительства' мы получим ошибку KeyError:

nikita = {
  'возраст':32,
  'пол':'мужской',
  'трудоустроен':True,
}

print(nikita['место жительства'])

# Вывод:
# KeyError: 'место жительства'

Если бы мы перебирали список словарей, эта ошибка могла бы прервать выполнение нашей программы. Да, конечно, мы бы могли использовать try, except — но зачем, если есть метод .get()?

Если значения, к которому мы хотим получить доступ, не существует — возвращается None. Это очень удобно!

nikita = {
  'возраст':32,
  'пол':'мужской',
  'трудоустроен':True,
}

print(nikita.get('место жительства'))

# Вывод:
# None

3. Облегчите перебор нескольких списков с помощью zip()

Порой возникают ситуации, когда у нас есть несколько коллекций (например, списков) и все их нужно перебрать. 

В примере №1 мы разбирали способ с применением range(len(collection)), но он не самый лучший.

Рассмотрим пример:

names = ['Никита', 'Дарья', 'Екатерина', 'Дмитрий']
ages = [32, 28, 37, 53]
gender = ['Мужчина', 'Женщина', 'Женщина', 'Мужчина']

# старый и скучный способ:
for_looped = []
for i in range(len(names)):
    for_looped.append((names[i], ages[i], gender[i]))

print(for_looped)

# Вывод:
# [('Никита', 32, 'Мужчина'), ('Дарья', 28, 'Женщина'), ('Екатерина', 37, 'Женщина'), ('Дмитрий', 53, 'Мужчина')]

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

Этот способ, конечно, рабочий. Но если коллекций станет слишком много, код выйдет громоздким. 

С помощью встроенной функции zip() мы можем все немного упростить.

Обратите внимание: функция zip() возвращает zip-объект, но с помощью приведения типов вы можете преобразовать его — например, с помощью list(), tuple() или dict().

А теперь рассмотрим тот же пример и снова вернем список кортежей:

names = ['Никита', 'Дарья', 'Екатерина', 'Дмитрий']
ages = [32, 28, 37, 53]
gender = ['Мужчина', 'Женщина', 'Женщина', 'Мужчина']

# перебор списков с помощью zip()
zipped = zip(names, ages, gender)
zipped_list = list(zipped)

print(zipped_list)

# Вывод:
# [('Никита', 32, 'Мужчина'), ('Дарья', 28, 'Женщина'), ('Екатерина', 37, 'Женщина'), ('Дмитрий', 53, 'Мужчина')]

Выглядит намного лучше, не так ли?

Также вы можете преобразовывать коллекции в словари напрямую. Но обратите внимание — коллекций должно быть только две. 

Например, вы хотите создать словарь, в котором пара ключ-значение — это имя:возраст. Сделать это можно так:

names = ['Никита', 'Дарья', 'Екатерина', 'Дмитрий']
ages = [32, 28, 37, 53]
gender = ['Мужчина', 'Женщина', 'Женщина', 'Мужчина']

ages = dict(zip(names,ages))

print(ages)

# Вывод:
# {'Никита': 32, 'Дарья': 28, 'Екатерина': 37, 'Дмитрий': 53}

Если вы сделаете то же самое, но коллекций будет больше двух — появится исключение ValueError.

4. Используем f-строки для упрощения вывода информации в консоль

Начиная с Python 3.8 f-строки могут быть использованы для самодокументирования — с помощью =

Это значит, что для того, чтобы вывести в консоль какое-то значение, вам больше не нужно писать f"variable_name = {variable_name}".

Рассмотрим пример: 

some_variable = "ПРИВЕТ!"

print(f"some_variable={some_variable}")

# Вывод:
# some_variable=ПРИВЕТ!

Вместо этого вы можете написать: 

some_variable = 'Привет!'

print(f'{some_variable=}')

# Вывод:
# some_variable='Привет!'

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

Заключение

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