1. 程式人生 > >複習+學習:type函式、生成器函式、zip函式、dict函式及yield

複習+學習:type函式、生成器函式、zip函式、dict函式及yield

在看《編寫高質量的程式碼 改善python 程式的91個建議》,“建議11:理解列舉替代實現的缺陷”,遇到如下程式碼:

def enum(*posarg, **keysarg):
	return type("Enum", (object,), dict(zip(posarg, xrange(len(posarg))), **keysarg))

對我這個python入門級選手,這段程式碼正好可以利用來複習以下知識:
. type函式
. zip函式
. * 和 **
. dict函式
. 生成器
也可以學習下面的新知識
. 如何自定義生成器函式
. yield函式


下面進入正題:

  • type 函式
	class type(name, bases, dict)
- 當只有第一個引數時,type函式使用者返回該物件的型別。可以利用type函式來查詢一個物件的型別。
- 當提供第二、三個引數時,type函式返回一個新型別。
	+ name: 類的名稱
	+ bases: 基類的元組
	+ dict: 字典,類內定義的名稱空間變數
  • zip函式:

    • 定義:zip([iterable, …]),接受一系列可迭代的物件作為引數,將物件中對應的元素打包成一個個tuple(元組),然後返回由這些 tuples組成的list(列表)。
    • 返回:返回一個zip物件,其內部元素為元組;可以轉化為列表或元組;
    • 傳入引數: 元組、列表、字典等迭代器。
  • zip函式:zip函式的“逆向操作”,直白一些理解的話,可以這麼解釋zip函式:

    • 首先,看作是一個zip函式,得到一個列表物件;
    • 然後,通過*操作符(拆包操作),將zip函式返回的列表物件的各“分量元素”解包成獨立的可迭代物件。
  • * 和 **

    • *表示從緊隨其後的迭代器中取出相應的“位置引數”
    • **表示所有未捕獲的“關鍵字引數”,都將被儲存在緊隨其後的字典物件中。
  • dict函式:建立字典

    • class dict(**kwarg) #通過傳入的關鍵字實參建立字典,如(a=‘a’, b=‘b’, c=‘c’);
    • class dict(mapping, **kwarg) # 從對映物件(鍵, 值對)建立(關鍵字實參可選);
    • class dict(iterable, **kwarg) # 從至少有兩個元素的可迭代物件建立(關鍵字實參可選。
    • 仔細閱讀構造器dict的定義:

1英文原文來自:python.org
中文是我自己翻譯的


Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.
返回一個新的字典,這個字典物件由可選的位置實參初始化而成,也可以由一系列關鍵字實參初始化而成(關鍵字實參可以為空)。

If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary.
如果沒提供位置實參,就產生一個空的字典,如果提供的位置實參是對映物件,就產生一個和該對映物件的“鍵-值對”相同的字典。除了上述兩種位置實參的型別,其它位置實參的型別必須是“可迭代物件”,可迭代物件中的每個元素自身也必須是可迭代的,並且有且只能有兩個物件,其中的第一個物件作為新字典的鍵,第二個物件是該鍵的值。如果鍵出現多次,則最後一個和鍵對應的值是新字典裡該鍵的值。

If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument.
如果提供了關鍵字實參,關鍵字實參所對應的鍵值會被新增到位置實參建立的新字典的後面,如果鍵已經存在,關鍵字實參中的值會替代位置實參中的值。


  • 如何自定義生成器函式:定義一個有迭代器行為的函式。
    • 利用yield函式,生成器函式與普通函式的區別是生成器返回的是一個迭代器物件,只有next()或send()方法能夠使生成器執行,像函式一樣呼叫生成器並不會直接執行,只會返回一個生成器物件。
    • 在呼叫生成器函式的過程中,每次遇到yield,函式會暫停並儲存當前所有執行資訊,返回yield後面的值,並在下次執行next()或send()方法時從當前位置繼續執行,直到遇到下一個yield或者滿足結束條件並結束函式為止。

以楊輝三角形為例:

def triangle():
    _list, new_list = [], []
    while True:
        length = len(_list)
        if length == 0:
            new_list.append(1)
        else:
            for times in range(length + 1):
                if times == 0:
                    new_list.append(1)
                elif times == length:
                    new_list.append(1)
                else:
                    temp = _list[times - 1] + _list[times]
                    new_list.append(temp)
        yield new_list #返回值,然後掛起函式,等待下一次呼叫
        _list = new_list.copy()#呼叫後會繼續執行下去
        new_list.clear()

n = 0
for result in triangle():
    n += 1
    print(result)
    if n == 10:
        break

  1. Mapping Types — dict ↩︎