>>> Последовательность из итератора
Последовательность можно задать явно, перечислив ее элементы, или аналитически, передав конструктору итератор, порождающий элементы последовательности. Наверное, самый популярный итератор – тот, что предоставляется объектом класса range
, получаемым с помощью функции range()
.
>>> it = iter(range(5))
>>> type(it)
<class 'range_iterator'>
>>> next(it)
0
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
4
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Последовательности с его помощью задаются так:
>>> list(range(5))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> bytes(range(127))
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
>>> Свой итератор
Чтобы написать итератор, нужно в собственном классе реализовать методы __iter__
и __next__
, которые вызываются функциями iter()
и next()
, соответственно. Пример:
>>> class Tens(object):
...
... def __init__(self, upper=100):
... self.currval = 0
... self.upper = upper
...
... def __iter__(self):
... return self
...
... def __next__(self):
... currval = self.currval
... if currval < self.upper:
... self.currval += 10
... return currval
... else:
... raise StopIteration
...
>>> list(Tens())
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> for i in Tens(50):
... print(i)
...
0
10
20
30
40
>>> Бесконечные итерации
Модуль itertools
стандартной библиотеки Python предоставляет ряд готовых итераторов. Среди них три бесконечных итератора, поэтому в следующих примерах нужно позаботиться о выходе из циклов:
>>> from itertools import count, cycle, repeat
>>> # считать от нуля
... for i, v in enumerate(count(0)):
... print(v)
... if i == 4:
... break
...
0
1
2
3
4
>>> # зациклить последовательность
... for i, v in enumerate(cycle([0, 1, 2])):
... print(v)
... if i == 4:
... break
...
0
1
2
0
1
>>> # повторять указанное значение
... for i, v in enumerate(repeat('hello')):
... print(v)
... if i == 4:
... break
...
hello
hello
hello
hello
hello
>>> Файл как итератор
Еще один замечательный итератор позволяет построчно читать файлы. В следующем примере вначале создается пятистрочный текстовый файл, а затем построчно читается и выводится:
>>> with open('file.txt', 'w') as f:
... f.writelines(['%i\n' % i for i in range(5)])
...
>>> with open('file.txt') as f:
... for line in f:
... print(line, end='')
...
0
1
2
3
4
Как обычно, с помощью итератора можно инициализировать последовательность:
>>> with open('file.txt') as f:
... lines = tuple(f)
...
>>> print(lines)
('0\n', '1\n', '2\n', '3\n', '4\n')
>>> Что умеет range
Тема функции range
не будет раскрыта, если не привести примеры со вторым и третьим параметрами: верхней границей диапазона и шагом приращения, соответственно.
>>> list(range(3, 9))
[3, 4, 5, 6, 7, 8]
>>> list(range(3, 9, 2))
[3, 5, 7]
Если шаг отрицательный, то первый параметр должен быть больше второго:
>>> list(range(9, 3, -1))
[9, 8, 7, 6, 5, 4]
>>> list(range(9, 3, -2))
[9, 7, 5]
Проверка на вхождение в range
учитывает, что диапазон разреженный при шаге, не равном единице:
>>> 10**90 in range(0, 10**100, 2)
True
>>> 10**90-1 in range(0, 10**100, 2)
False
Комментариев нет:
Отправить комментарий