Python: поради, рекомендації, ідіоми

6 хв. читання

Писати код на Python легше і швидше ніж на інших мовах – це одна з його основних переваг. Багато хороших трюків та ідіом дозволяють писати кращий, читабельніший код. Ця стаття пропонує колекцію деяких моїх найбільш улюблених ідіом.

enumerate

Досить часто потрібно відстежувати індекси елементів в циклі. Звісно, ми могли б використовувати додаткову змінну для реалізації лічильника, але Python дає нам зручний інструмент – функція enumerate().

students = ('James', 'Andrew', 'Mark')
for i, student in enumerate(students):
    print i, student
# виведе:
# 0 James
# 1 Andrew
# 2 Mark 

set

set - корисна структура даних, схоже на список, але кожне значення в ньому унікальне. Окрім створення списку з лише унікальними значеннями елементів, вона має ще декілька інших корисних операцій, які ми зараз розглянемо. Для прикладу, різні способи перевірки списків.

colours = set(['red', 'green', 'blue', 'yellow', 'orange', 'black', 'white'])
 
input_values = {'red', 'black', 'pizza'}
 
# отримуємо список кольорів
valid_values = input_values.intersection(colours)
 
print valid_values
# виведе: set(['black', 'red'])
 
# отримуємо список "не кольорів"
invalid_values = input_values.difference(colours)
 
print invalid_values
# виведе set(['pizza'])
 
# виключення, якщо знайдено щось некоректне
if not input_values.issubset(colours):
    raise ValueError("Invalid colour: " + ", ".join(input_values.difference(colours)))

Контрольні вирази

With

Цей вираз корисний при доступі до будь-чого, що підтримується протоколом управління контексту. Це в основному гарантує, що не потрібно додаткових дій, наприклад, закриття файлу. Для прикладу, як відкрити файл:

with open('/etc/passwd', 'r') as f:
    print f.read()

For … else

Дозволяє виконати деякий код, якщо цикл не буде перервано за допомогою break. В основному, це замінює необхідність додаткової змінної для відстеження виходу з циклу. (детальніше)

for file_name in file_list:
    if is_build_file(file_name):
        break
else: # якщо не було break
    make_built_file()
 

Умовні вирази

Python дозволяє використовувати умовні вирази, отже замість використання If … else з присвоюванням змінної в кожній гілці, можна зробити так:

# number стає завжди непарним
number = count if count % 2 else count - 1
 
# викликати функцію якщо об'єкт не None 
name = user.name() if user is not None else 'Guest'
print "Hello", name

Спискові вирази

Спискові вирази (або спискові включення) перебудовують список через цикл з додаванням елементів. Порівняйте наступне:

numbers = [1, 2, 3, 4, 5, 6, 7]
squares = []
for num in numbers:
    squares.append(num * num)
 
# використання спискових виразів
squares = [num * num for num in numbers]

Ми можемо це ускладнити, додавши фільтр:

numbers = [1, 2, 3, 4, 5, 6, 7]
 
# квадрат всіх непарних елементів
squares = [num * num for num in numbers if num % 2]
 
# парні числа помножити на 2, непарні - на 3
mul = [num * 3 if num % 2 else num * 2 for num in numbers]

Словникові вирази

Інколи необхідно збудувати словник, як в прикладі нижче. Тут нам на допомогу прийдуть словникові вирази. Обидва приклади міняють місцями ключ і значення.

teachers = {
    'Andy': 'English',
    'Joan': 'Maths',
    'Alice': 'Computer Science',
}
# використання спискових виразів
subjects = dict((subject, teacher) for teacher, subject in teachers.items())
 
# використання словникових виразів
subjects = {subject: teacher for teacher, subject in teachers.items()}

zip()

Функція zip() приймає номер ітерації і з'єднує н-ний елемент кожного списку в тьюпл.

names = ('James', 'Andrew', 'Mark')
for i, name in zip(random_numbers(), names):
    print i, name
 
# виведе:
# 288 James
# 884 Andrew
# 133 Mark

Цей приклад виводить імена з випадковим номером. Зауважте, що zip() зупиниться, як тільки закінчиться хоча б один із списків.

Ми можемо зробити щось подібне, щоб отримати словник з імен та випадкових чисел. Наприклад:

dict(zip(names, random_numbers()))
 
# виведе: {'James': 992, 'Andrew': 173, 'Mark': 329}

Колекції

Python поставляється разом з модулем, що містить тип даних Collections.

defaultdict

Корисний при додаванні списків у словник. Можна використовувати звичний dict(), але тоді необхідно буде перевіряти наявність ключа перед додаванням, при використанні defaultdict – це робиться автоматично. Для прикладу:

from collections import defaultdict
 
order = (
    ('Mark', 'Steak'),
    ('Andrew', 'Veggie Burger'),
    ('James', 'Steak'),
    ('Mark', 'Beer'),
    ('Andrew', 'Beer'),
    ('James', 'Wine'),
)
 
group_order = defaultdict(list)
 
for name, menu_item in order:
    group_order[name].append(menu_item)
 
print group_order
 
# виведе
# defaultdict(<type 'list'="">, {
#     'James': ['Steak', 'Wine'],
#     'Andrew': ['Veggie Burger', 'Beer'],
#     'Mark': ['Steak', 'Beer']
# })

Ми можемо й порахувати їх:

order_count = defaultdict(int)
 
for name, menu_item in order:
    order_count[menu_item] += 1
 
print order_count
 
# виведе:
# defaultdict(<type 'int'="">, {
#     'Beer': 2, 
#     'Steak': 2, 
#     'Wine': 1, 
#     'Veggie Burger': 1
# })

Counter

Останній приклад трохи зайвий, тому що в Collections міститься готовий клас для цього – Counter. В цьому випадку, спершу потрібно витягнути другий елемент з кожного тьюпла. Зробити це можна через генераторні вирази.

from collections import Counter
 
order_count =  Counter(menu_item for name, menu_item in order)
print order_count
 
# виведе:
# Counter({
#    'Beer': 2,
#    'Steak': 2,
#    'Wine': 1,
#    'Veggie Burger': 1
# })

Інший, можливо кращий, приклад – підрахунок всіх ліній тексту в файлі. Це виглядає дуже просто.

with open('/some/file', 'r') as f:
    line_count = Counter(f)

Якщо вам сподобалось, поширте цю статтю в соц. мережах, можливо ще комусь вона стане у нагоді. А в коментарях напишіть, які цікаві функції/класи в Python ви використовуєте.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.6K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація