【读书笔记】深入理解Python特性(六)

1. 迭代器可以返回含有任意个元素的元组,然后在for循环内解包

>>> emails = {
...    Bob: bob@example.com,
...    Alice: alice@example.com
... }

>>> for name, email in emails.items():
...    print(f{name} -> {email})
Bob -> bob@example.com
Alice -> alice@example.com

2. 解析式

    解析式也叫生成式,包括列表解析式,集合解析式,字典解析式 以列表解析式为例,for循环转化为解析式的模板:
# template 1
values = []
for item in collection:
    values.append(expression)
# -->
values = [expression for item in collection]


# template 2
values = []
for item in collection:
    if condition:
        values.append(expression)
# -->
values = [expression 
          for item in collection 
          if condition]

3. 列表切片

    切片语法[start:stop:step] 不提供step,则默认step为1。 列表复制[::](注意:该复制方法为浅复制,list()也是浅复制)
# [::]是浅复制举例
>>> a = [[1, 2], [3, 4]]
>>> b = a[::]
>>> a
[[1, 2], [3, 4]]
>>> b
[[1, 2], [3, 4]]
>>> a[0][0] = 10
>>> a
[[10, 2], [3, 4]]
>>> b
[[10, 2], [3, 4]]

可以看出b随a变更,是因为浅复制只复制了元素的引用。

    列表逆序[::-1] 清空列表:del [:]。注意:清空列表和列表对象赋值为空是两回事。清空列表以后访问所有指向这个列表的引用都会得到一个空列表,列表对象赋值为空只是创建了一个空列表然后把对象绑定到这个空列表上。

4. 迭代器和生成器

    可迭代对象通过__iter__方法返回迭代器,通过__next__方法返回迭代值,通过抛出异常StopIteration终止迭代。

如下例所示:

class BoundedRepeater:
    def __init__(self, value, max_repeats):
        self.value = value
        self.max_repeats = max_repeats
        self.count = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.count >= self.max_repeats:
            raise StopIteration
        self.count += 1
        return self.value

    # 兼容Python2
    def next(self):
        return self.__next__()
    生成器函数是迭代器的一种语法糖,用于编写支持迭代器协议的对象。上述代码可以用生成器函数重写如下:
def bounded_repeater(value, max_repeats):
    for i in range(max_repeats):
        yield value
    生成器表达式是生成器函数的一种语法糖,基本模式如下:
# 生成器函数
def generator():
    for item in collection:
        if condition:
            yield expression
# 对应的生成器表达式
genexpr = (expression for item in collection if condition)

上述的bounded_repeater可以改写如下:

bounded_repeater = (Hi for i in range(3))
    如果生成器表达式时作为函数的单个参数使用,可以省略生成器表达式的括号:
sum((x for x in range(10)))
# 可以简写成
sum(x for x in range(10))
经验分享 程序员 微信小程序 职场和发展