Многие примеры кода, показанные в первых главах этой книги, демонстрируют, что порядок ключей в словаре нельзя предсказать: вы можете добавить в определенном порядке ключи a, b и c, но функция keys() вернет результат "c, a, b". Рассмотрим модифицированный пример из главы 1:

>>> quotes = {

…·····'Moe': 'A wise guy, huh?',

…·····'Larry': 'Ow!',

…·····'Curly': 'Nyuk nyuk!',

…·····}

>>> for stooge in quotes:

…··print(stooge)

Larry

Curly

Moe

Словарь OrderedDict() запоминает порядок, в котором добавлялись ключи, и возвращает их в том же порядке с помощью итератора. Попробуем создать OrderedDict из последовательности кортежей вида «ключ — значение»:

>>> from collections import OrderedDict

>>> quotes = OrderedDict([

…·····('Moe', 'A wise guy, huh?'),

…·····('Larry', 'Ow!'),

…·····('Curly', 'Nyuk nyuk!'),

…·····])

>>>

>>> for stooge in quotes:

…·····print(stooge)

Moe

Larry

Curly

<p>Стек + очередь == deque</p>

deque (произносится как «дэк») — это двухсторонняя очередь, которая имеет возможности стека и очереди. Она полезна, когда вы хотите добавить и удалить элементы с любого конца последовательности. В следующем примере мы будем двигаться с обоих концов слова к его середине, чтобы увидеть, является ли оно палиндромом. Функция popleft() удаляет крайний слева элемент deque и возвращает его, функция pop() удаляет крайний справа элемент и возвращает его. Вместе они двигаются с концов слова к его середине. Работа будет продолжаться до тех пор, пока крайние символы совпадают и пока не будет достигнута середина:

>>> def palindrome(word):

…·····from collections import deque

…·····dq = deque(word)

…·····while len(dq) > 1:

…········if dq.popleft()!= dq.pop():

…············return False

…·····return True

>>> palindrome('a')

True

>>> palindrome('racecar')

True

>>> palindrome('')

True

>>> palindrome('radar')

True

>>> palindrome('halibut')

False

Я воспользовался этим примером, чтобы было проще проиллюстрировать работу deque. Если вы действительно хотите создать программу, которая определяет палиндромы, гораздо проще было бы сравнивать строку с ее копией, вывернутой наизнанку. В Python строковой функции reverse() не существует, но можно обратить строку с помощью разбиения, как показано здесь:

>>> def another_palindrome(word):

…·····return word == word[::-1]

>>> another_palindrome('radar')

True

>>> another_palindrome('halibut')

False

<p>Итерируем по структурам кода с помощью itertools</p>

itertools содержит особые функции итератора. Каждая из них возвращает один элемент при каждом вызове из цикла for … in и запоминает свое состояние между вызовами.

Функция chain() проходит по своим аргументам, как если бы они были единым итерабельным объектом:

>>> import itertools

>>> for item in itertools.chain([1, 2], ['a', 'b']):

…·····print(item)

1

2

a

b

Функция cycle() является бесконечным итератором, проходящим в цикле по своим аргументам:

>>> import itertools

>>> for item in itertools.cycle([1, 2]):

…·····print(item)

1

2

1

2

.

.

.

…и т. д.

Функция accumulate() подсчитывает накопленные значения. По умолчанию она высчитывает сумму:

>>> import itertools

>>> for item in itertools.accumulate([1, 2, 3, 4]):

…·····print(item)

1

3

6

10

В качестве второго аргумента функции accumulate() вы можете передать функцию, и она будет использована вместо сложения. Функция должна принимать два аргумента и возвращать одно значение. В этом примере высчитывается произведение:

>>> import itertools

>>> def multiply(a, b):

…·····return a * b

>>> for item in itertools.accumulate([1, 2, 3, 4], multiply):

…·····print(item)

1

2

6

24

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

Перейти на страницу:

Все книги серии Бестселлеры O'Reilly

Похожие книги