Итераторы

Итераторы вокруг нас

Вычислимые последовательности.

Протокол итерируемой последовательности:

Как сделать итератор:

iter() от всего подряд

Использование итераторов в протоколах:

Генераторы

Как задать самому?

ИРЛ: вычислимые последовательности, в т. ч. бесконечные

Параметрические генераторы

В генератор можно затолкать значение на каждом обороте (оно прочтётся yield-ом).

   1 >>> def biased(init):
   2 ...     bias = yield init
   3 ...     while bias:
   4 ...         init += bias*2+1
   5 ...         bias = yield init
   6 ...
   7 >>> g = biased(10)
   8 >>> next(g) # или, что то же самое, g.send(None)
   9 10
  10 >>> g.send(5)
  11 21
  12 >>> g.send(5)
  13 32
  14 >>> g.send(-1)
  15 31
  16 >>> g.send(100500)
  17 201032
  18 >>> g.send(0)
  19 Traceback (most recent call last):
  20   File "<stdin>", line 1, in <module>
  21 StopIteration

Зачем это может быть нужно??

Itertools (сколько успеем)

itertools

Д/З

  1. Прочитать
  2. EJudge: LookSay 'Прочти это вслух'

    Написать генератор-функцию LookSay() цифр последовательности Конвея «Look and Say». Сама последовательность должна быть целочисленной. Описание в Википедии

    Input:

    for i, l in enumerate(LookSay()):
        print(f"{i}: {l}")
        if i > 10:
            break
    Output:

    0: 1
    1: 1
    2: 1
    3: 2
    4: 1
    5: 1
    6: 2
    7: 1
    8: 1
    9: 1
    10: 1
    11: 1
  3. EJudge: ChainSlice 'Режем лазанью'

    Написать Генератор-функцию chainslice(begin, end, seq0, seq1, …), которая принимает не менее трёх параметров: два целых числа и не менее одной последовательности. Рассмотрим последовательность seq, образованную всеми элементами seq0, затем — всеми элементами seq1, и т. д. Вернуть эта функция должна итератор, пробегающий элементы этой последовательности seq с №begin до №end-1 включительно.

    Input:

    print(*(chainslice(17, 33, range(7),  range(8),  range(6),  range(9),  range(5))))
    Output:

    2 3 4 5 0 1 2 3 4 5 6 7 8 0 1 2
  4. EJudge: VarRandom 'Случайные диапазоны'

    Написать генератор-функцию randomes(seq), которой передаётся на вход последовательность пар seq — диапазоны для функции random.randint(). На выходе должен быть генератор, который бесконечно возвращает случайные числа по одному из каждого диапазона. Сами пары тоже могут оказаться итераторами. Пример вывода, разумеется, не эталонный.

    Input:

       1 for e in zip(randomes([(1, 3), (100, 200), (-10, 10)]), range(7)):
       2     print(e[0])
    
    Output:

    1
    123
    -3
    3
    177
    7
    2
  5. EJudge: SeqJoin 'Слияние'

    Написать генератор-функцию joinseq(seq0, seq1, …), принимающую на вход произвольное количество (возможно, бесконечных) последовательностей. Порождаемый ею генератор должен всякий раз возвращать наименьший из начальных элементов этих последовательностей. Если таких несколько, используется самый первый. Если последовательность закончилась, она больше не учитывается. Итератор завершается, когда все последовательности иссякли.

    • Условие: использовать обработку исключений в этой задаче нельзя.

    Input:

       1 print("".join(joinseq("abs", "qr", "azt")))
    
    Output:

    aabqrszt

LecturesCMC/PythonIntro2021/07_Iterators (last edited 2021-10-28 11:17:24 by FrBrGeorge)