Шаг 12.
Python: сборник рецептов.
Структуры данных и алгоритмы. Присваивание имен срезам

    На этом шаге мы рассмотрим использование функции slice().

Задача

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

Решение

    Предположим, что у вас есть код, который вытаскивает определенные поля с данными из строковых записей с фиксированным набором полей (т. е. из файла с плоской структурой или похожего формата):

###### 0123456789012345678901234567890123456789012345678901234567890'
record = '....................100 .......513.25 ..........'
cost = int(record[20:32]) * float(record[40:48])

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

SHARES = slice(20, 32)
PRICE = slice(40, 48)
cost = int(record[SHARES]) * float(record[PRICE])

    В последнем примере вы избежали появления кучи загадочных индексов, и код стал проще и яснее.

Обсуждение

    Общее правило таково: написание кода с большим количеством неоформленных индексов ведет к проблемам с читабельностью и поддерживаемостью. Например, если вы вернетесь к такому коду через год, то наверняка не сразу вспомните, как и о чем вы думали, когда все это писали. Приведенное выше решение - простой путь к более ясному обозначению того, что делает ваш код.

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

>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[2:4]
[2, 3]
>>> items[a]
[2, 3]
>>> items[a] = [10, 11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
>>> del items[a]
>>> items
[0, 1, 4, 5, 6]
>>> 

    Если у вас есть экземпляр slice(), сохраненный в переменной s, вы можете получить больше информации о нем, если посмотрите на атрибуты s.start, s.stop и s.step. Например:

>>> a = slice(10, 50, 2)
>>> a.start
10
>>> a.stop
50
>>> a.step
2
>>> 

    Также вы можете наложить срез на последовательность определенного размера, используя его метод indices(size). Он возвращает кортеж (start, stop, step), где все значения соответственно ограничены, чтобы вписаться в границы (дабы избежать возбуждения исключений IndexError при индексировании). Например:

>>> s = 'HelloWorld'
>>> a = slice(5, 50, 2)
>>> a.indices(len(s))
(5, 10, 2)
>>> for i in range(*a.indices(len(s))):
	print(s[i])

	
W
r
d
>>> 

    На следующем шаге мы рассмотрим определение наиболее часто встречающихся элементов в последовательности.




Предыдущий шаг Содержание Следующий шаг