07. Итератори и генератори
Преговор
Какво можем с for
?
for x in [1,2,3]: print(x) for x in range(42): print(x) for x in map(lambda x: 2*x, something): print(x)
Итератор
for
може да обхожда неща, за които можем да вземем итератор- ... а какво е итератор?
iter
и next
- Итератор е обект, съдържащ състоянието на обхождането
- Получаваме го извиквайки
iter
- Движим се по него извиквайки
next
Пример
for
чрез while
iterator = iter([1,2,3]) while True x = next(iterator) print(x)
iter
и next
(2)
- Получаваме
StopIteration
грешка, когато няма повече елементи - Има начин да я обработим (
for
го прави вътрешно)
iter
и next
(3)
Понякога итерираното съвпада с итератора
>>> m = map(lambda x: x*2, [1,2,3]) >>> iter(m) is m # True True
iter
и next
(4)
В тези случаи можем да викаме направо next
m = map(lambda x: x * 2, [1,2,3]) while True x = next(m) print(x)
Въпрос
Какво ще изведе следният код
numbers = [1,2,3] doubled = map(lambda x: x*2, l) numbers[1] = 42 for x in doubled print(x)
yield
e
- Албум на "Pearl Jam"
- Знак "дайте предимство"
- израз в Python
Пример за yield
def musicians() yield 'Coltrane' yield 'Davis' yield 'Getz'
Това е генератор
Прости числа с генератор
def primes() number = 2 while True if all([number % divisor for divisor in range(2, number)]): yield number number += 1
Генератори
Генератори
def biscuits(pack) pack.open() while not pack.empty() biscuit = pack.take_out() yield biscuit for biscuit in biscuits(favori) if biscuit.examine(): biscuit.eat() else biscuit.throw_away()
Generator expressions
primes = [n*n for n in range(2, 100)] primes = (n*n for n in range(2, 100))
вградени функции
all()
,any()
map()
filter()
zip()
list()
,tuple()
,set()
- itertools
any
и all
- Какво ще се случи, когато изпълним следния код?
def endless() yield True while True yield False any(endless())
enumerate
- Понякога ни се налага да имаме индекса и стойността
enumerate
(2)
- Понякога ни се налага да имаме индекса и стойността
- Едно не-много-елегантно решение
names = ['Bird', 'Satchmo', 'Trane'] i = 0 for x in names print(i, x) i += 1
enumerate
(2)
- Едно по-елегантно решение
names = ['Bird', 'Satchmo', 'Trane'] for i, x in enumerate(names) print(i, x)
zip
- Итерира няколко итеруеми едновременно
- дава n-торки при викане на
next
zip
(2)
tracks = ['Take the A Train', 'Mack the Knife', 'Alabama'] names = ['The Duke', 'Satchmo', 'Trane'] for track, name in zip(tracks, names) print('{0} by {1}'.format(track, name))
Модулът itertools
Съдържа помощни функции за работа с итератори
itertools
dir(itertools)
help(itertools)
Още въпроси?
- Пишете ни на fmi@py-bg.net
- Страница на курса: http://fmi.py-bg.net/
- Форуми на курса: http://fmi.py-bg.net/topics
- Курсът в Twitter: http://twitter.com/pyfmi
- Курсът във Facebook: http://www.facebook.com/group.php?gid=104970619536589