1. 程式人生 > 其它 >[2021 Spring] CS61A 學習筆記 lecture 15 Iterators + Generators

[2021 Spring] CS61A 學習筆記 lecture 15 Iterators + Generators

主要內容:迭代器和生成器

目錄

Iterators

An iterator is an object that provides sequential access to values, one by one.

  • iter(iterable) returns an iterator over the elements of an iterable.
  • next(iterator) returns the next element in an iterator.

Iterators vs. For loops

一般情況下使用for迴圈進行迭代,除非有特殊理由需要用到next() / iter() / StopIteration, for迴圈易讀也更優化。
迭代器:

ranked_chocolates = ("Dark", "Milk", "White")
chocorator = iter(ranked_chocolates)
try :
whileTrue:
        choco = next(chocorator)
        print(choco)
except StopIteration:
    print("No more left!")

for 迴圈(其實是一種語法糖)

ranked_chocolates = ("Dark", "Milk", "White")
for  chocolate in ranked_chocolates:
    print(chocolate)

Functions that return iterators

返回迭代器的函式有:reversed(sequence), zip(*iterables), map(func, iterable, ...), filter(func, iterable)

Bonus 1:生成迭代器後,修改iterable的值是很危險的

使用reversed生成迭代器後,

  1. 在原列表後新增元素,迭代器不會新增。
  2. 修改原列表中的值,迭代器返回值也會被修改,但是不會重新排序。
  3. list(iterator)會生成新的列表,原列表中值的變化不會改變新列表的值。

Generators

A generator is a type of iterator that yields results from a generator function.

How generators work

Looping over generators

生成器是一種特殊的迭代器。

Why use generators?

只需要少量元素時,使用生成器相比生成整個序列可以節省很大的空間。

Yielding from iterables

def a_then_b (a, b):
    yield from a
    yield from b
list(a_then_b(["Apples" , "Aardvarks"], ["Bananas", "BEARS"]))

Recursive yield from

def factorial(n, accum):
    if n == 0:
        yield accum
    else:
        yield from factorial(n - 1, n * accum)

for num in factorial(3, 1):
    print(num)

Recursive generators for trees

def leaves(t):
    yield label(t)
    for c in branches(t):
        yield from leaves(c)
t = tree(20, [tree( 12,
               [tree(9,
                  [tree(7), tree( 2)]),
                tree(3)]),
              tree(8,
               [tree(4), tree( 4)])])
leave_gen = leaves(t)
next(leave_gen)