Писати код на 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 ви використовуєте.
Ще немає коментарів