【讀書筆記】深入理解Python特性(六)

1. 迭代器可以返回含有任意個元素的元組,然後在for循環內解包

>>> emails = {
...    'Bob': '[email protected]',
...    'Alice': '[email protected]'
... }

>>> for name, email in emails.items():
...    print(f'{name} -> {email}')
'Bob -> [email protected]'
'Alice -> [email protected]'

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))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章