# Итераторы¶

In [1]:
class Range:
def __init__(self, start, stop):
self._current = start
self._stop = stop

def __iter__(self):
return self

def __next__(self):
if self._current < self._stop:
result = self._current
self._current += 1
return result
else:
raise StopIteration

for e in Range(0, 3):
print(e)

i = Range(0, 3)
print(next(i))
print(next(i))
i = iter(i)
print(next(i))
print(next(i))

0
1
2
0
1
2

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-1-362d28f4cab1> in <module>()
23 i = iter(i)
24 print(next(i))
---> 25 print(next(i))

<ipython-input-1-362d28f4cab1> in __next__(self)
13             return result
14         else:
---> 15             raise StopIteration
16
17 for e in Range(0, 3):

StopIteration: 

# Генераторные функции¶

In [2]:
def range(start, stop):
current = start
while current < stop:
yield current
current += 1

g = range(0, 3)
for e in g:
print(e)

g = range(0, 3)
print(next(g))
print(next(g))
print(next(g))
print(next(g))

0
1
2
0
1
2

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-2-4a5e9870810c> in <module>()
14 print(next(g))
15 print(next(g))
---> 16 print(next(g))

StopIteration: 
In [3]:
def range(start, stop):
current = start
while current < stop:
reset = yield current
if reset is not None:
current = reset - 1
current += 1

g = range(0, 3)
print(next(g))
print(next(g))
print(g.send(0))
print(next(g))

0
1
0
1


## yield from¶

In [4]:
def range(start, stop):
current = start
while current < stop:
reset = yield current
if reset is not None:
current = reset - 1
current += 1

def two_ranges(start, stop):
for x in range(start, stop):
yield x
for x in range(start, stop):
yield x

g = two_ranges(0, 3)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

0
1
2
0
1
2

In [5]:
g = two_ranges(0, 3)
print(next(g))
print(next(g))
print(g.send(-1))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

0
1
2
0
1
2

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-5-f319fcd1c73f> in <module>()
6 print(next(g))
7 print(next(g))
----> 8 print(next(g))

StopIteration: 
In [6]:
def range(start, stop):
current = start
while current < stop:
reset = yield current
if reset is not None:
current = reset - 1
current += 1

def two_ranges(start, stop):
yield from range(start, stop)
yield from range(start, stop)

g = two_ranges(0, 3)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

0
1
2
0
1
2

In [7]:
g = two_ranges(0, 3)
print(next(g))
print(next(g))
print(g.send(-1))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

0
1
-1
0
1
2
0


# Генераторные выражения¶

In [1]:
g = (x for x in [1, 2, 3])
print(next(g))
print(next(g))
print(next(g))
print(next(g))

1
2
3

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-1-bf891876bdc5> in <module>()
3 print(next(g))
4 print(next(g))
----> 5 print(next(g))

StopIteration: 
In [2]:
g = (x * x for x in [1, 2, 3])
for e in g:
print(e)

1
4
9

In [3]:
g = (x * x for x in range(10) if x % 2 == 0)
list(g)

Out[3]:
[0, 4, 16, 36, 64]
In [4]:
g = (x * y for x in range(3) for y in range(4))
list(g)

Out[4]:
[0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6]

# Comprehensions¶

In [5]:
a = [x * x for x in [1, 2, 3]]
a

Out[5]:
[1, 4, 9]
In [6]:
s = {x * x for x in [1, 2, 3]}
s

Out[6]:
{1, 4, 9}
In [7]:
d = {x: x * x for x in [1, 2, 3]}
d

Out[7]:
{1: 1, 2: 4, 3: 9}

# itertools¶

In [8]:
import itertools

i = itertools.chain(range(3), range(5), range(2))
for e in i:
print(e)

0
1
2
0
1
2
3
4
0
1

In [9]:
i = itertools.combinations(range(4), 3)
list(i)

Out[9]:
[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
In [10]:
i = itertools.permutations(range(4), 3)
list(i)

Out[10]:
[(0, 1, 2),
(0, 1, 3),
(0, 2, 1),
(0, 2, 3),
(0, 3, 1),
(0, 3, 2),
(1, 0, 2),
(1, 0, 3),
(1, 2, 0),
(1, 2, 3),
(1, 3, 0),
(1, 3, 2),
(2, 0, 1),
(2, 0, 3),
(2, 1, 0),
(2, 1, 3),
(2, 3, 0),
(2, 3, 1),
(3, 0, 1),
(3, 0, 2),
(3, 1, 0),
(3, 1, 2),
(3, 2, 0),
(3, 2, 1)]
In [11]:
i = itertools.cycle(range(4))
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))

0
1
2
3
0
1
2
3
0

In [12]:
i = itertools.product("abcdefgh", range(1, 9))
list(i)

Out[12]:
[('a', 1),
('a', 2),
('a', 3),
('a', 4),
('a', 5),
('a', 6),
('a', 7),
('a', 8),
('b', 1),
('b', 2),
('b', 3),
('b', 4),
('b', 5),
('b', 6),
('b', 7),
('b', 8),
('c', 1),
('c', 2),
('c', 3),
('c', 4),
('c', 5),
('c', 6),
('c', 7),
('c', 8),
('d', 1),
('d', 2),
('d', 3),
('d', 4),
('d', 5),
('d', 6),
('d', 7),
('d', 8),
('e', 1),
('e', 2),
('e', 3),
('e', 4),
('e', 5),
('e', 6),
('e', 7),
('e', 8),
('f', 1),
('f', 2),
('f', 3),
('f', 4),
('f', 5),
('f', 6),
('f', 7),
('f', 8),
('g', 1),
('g', 2),
('g', 3),
('g', 4),
('g', 5),
('g', 6),
('g', 7),
('g', 8),
('h', 1),
('h', 2),
('h', 3),
('h', 4),
('h', 5),
('h', 6),
('h', 7),
('h', 8)]