a, *rest = [1, 2, 3]
# a = 1, rest = [2, 3]
a, *middle, c = [1, 2, 3, 4]
# a = 1, middle = [2, 3], c = 4
Если вам необходимо присвоить какое-то значение во время распаковки, но сама переменная не нужна, воспользуйтесь двойным подчеркиванием (__):
filename = 'foobar.txt'
basename, __, ext = filename.rpartition('.')
Многие руководства по стилю для Python рекомендуют использовать одинарное подчеркивание (_) для подобных переменных вместо двойного (__), о котором говорится здесь. Проблема в том, что одинарное подчеркивание зачастую применяется как псевдоним для функции gettext.gettext() и как интерактивное приглашение сохранить значение последней операции. Двойное подчеркивание выглядит точно так же прозрачно и почти так же удобно, снижает риск случайного переписывания переменной с именем «_» в обоих сценариях.
Используйте оператор списка Python * для того, чтобы создать список, состоящий из одинаковых неизменяемых элементов:
>>> four_nones = [None] * 4
>>> print(four_nones)
[None, None, None, None]
Одинаковые объекты должны иметь одинаковые значения хэша. В документации к Python содержится более подробная информация.
Однако будьте осторожны при работе с изменяемыми объектами: поскольку списки изменяемы, оператор * создаст список, состоящий из N ссылок на него самого, и это вряд ли вас устроит. Поэтому используйте списковое включение:
| Плохой код | Хороший код |
|---|---|
>>> four_lists = [[]] * 4 |
>>> four_lists = [[] for __ in range(4)] |
>>> four_lists[0].append("Ni") |
>>> four_lists[0].append("Ni") |
>>> print(four_lists) |
>>> print(four_lists) |
[['Ni'], ['Ni'], ['Ni'], ['Ni']] |
[['Ni'], [], [], []] |
Распространенная идиома для создания строк состоит в том, чтобы использовать функцию str.join() для пустой строки. Данная идиома может быть применена к спискам и кортежам:
>>> letters = ['s', 'p', 'a', 'm']
>>> word = ''.join(letters)
>>> print(word)
spam
Иногда требуется выполнить поиск по коллекции элементов. Изучим два варианта: списки и множества.
Для примера рассмотрим следующий код:
>>> x = list(('foo', 'foo', 'bar', 'baz'))
>>> y = set(('foo', 'foo', 'bar', 'baz'))
>>>
>>> print(x)
['foo', 'foo', 'bar', 'baz']
>>> print(y)
{'foo', 'bar', 'baz'}
>>>
>>> 'foo' in x True
>>> 'foo' in y True
Даже несмотря на то что обе булевых проверки на наличие в списке и множестве выглядят идентично, а foo in y учитывает тот факт, что множества (и словари) в Python являются хэш-таблицами[40], производительность для этих двух примеров будет различной. Python должен пройти по каждому элементу списка в поисках совпадения, на что уходит много времени (это заметно при увеличении размера коллекций). Но поиск ключей во множестве может быть выполнен быстро с помощью поиска по хэшу. Кроме того, множества и словари не могут содержать повторяющихся записей и идентичных ключей. Для получения более подробной информации поинтересуйтесь семинаром на эту тему на ресурсе Stack Overflow (http://stackoverflow.com/questions/513882).
Зачастую блоки try/finally используются для управления ресурсами вроде файлов или блокировок потоков в случае генерации исключений. В PEP 343 (https://www.python.org/dev/peps/pep-0343/) представлены оператор with и протокол управления контекстом (в версиях 2.5 и выше) — идиома, позволяющая заменить блоки try/finally на более читаемый код. Протокол состоит из двух методов, __enter__() и __exit__(), которые при реализации для объекта позволяют использовать этот объект в операторе with, например так:
>>> import threading
>>> some_lock = threading.Lock()
>>>
>>> with some_lock:
… ····# Создать Землю 1, запустить ее на десять миллионов лет…
40
Кстати, именно поэтому только хэшируемые объекты можно хранить во множествах или использовать как ключи для словарей. Чтобы ваши объекты Python стали хэшируемыми, определите функцию-член object.__hash__(self), которая возвращает целое число.