<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Chapter 19 The Goodies 額外補充 One of my goals for this book has been to teach you as little Python as possible. When there were two ways to do something, I picked one and avoided mentioning the other. Or sometimes I put the second one into an exercise. > 我在本書中的一個目標就是盡量少教你 Python(譯者注:而要多教編程)。有的時候完成一個目的有兩種方法,我都會只選擇一種而不提其他的。或者有的時候我就把第二個方法放到練習里面。 Now I want to go back for some of the good bits that got left behind. Python provides a number of features that are not really necessary—you can write good code without them—but with them you can sometimes write code that’s more concise, readable or efficient, and sometimes all three. > 現在我就要往回倒車一下,撿起一些當時略過的重要內容來給大家講一下。Python 提供了很多并非必須的功能—你完全可以不用這些功能也能寫出很好的代碼—但用這些功能有時候能讓你的代碼更加簡潔,可讀性更強,或者更有效率,甚至有時候能兼顧這三個方面。 ## 19.1 Conditional expressions 條件表達式 We saw conditional statements in Section 5.4. Conditional statements are often used to choose one of two values; for example: > 在5.4中,我們見到了條件語句。條件語句往往用于二選一的情況下;比如: ```Python if x > 0: y = math.log(x) else: y = float('nan') ``` This statement checks whether x is positive. If so, it computes math.log. If not,math.log would raise a ValueError. To avoid stopping the program, we generate a “NaN”, which is a special floating-point value that represents “Not a Number”. > 這個語句檢查了 x 是否為正數。如果為正數,程序就計算對數值 math.log。如果非正,對數函數會返回一個值錯誤 ValueError。要避免因此而導致程序異常退出,咱們就生成了一個『NaN』,這個符號是一個特別的浮點數的值,表示的意思是『不是一個數』。 We can write this statement more concisely using a conditional expression: > 用一個條件表達式能讓這個語句更簡潔: ```Python y = math.log(x) if x > 0 else float('nan') ``` You can almost read this line like English: “y gets log-x if x is greater than 0; otherwise it gets NaN”. Recursive functions can sometimes be rewritten using conditional expressions. For example, here is a recursive version of factorial: > 上面這行代碼讀起來就跟英語一樣了:『如果 x 大于0就讓 y 等于 x 的對數;否則的話就返回 Nan』。 > 遞歸函數有時候也可以用這種條件表達式來改寫。例如下面就是分形函數 factorial 的一個遞歸版本: ```Python def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) ``` We can rewrite it like this: > 我們可以這樣改寫: ```Python def factorial(n): return 1 if n == 0 else return n * factorial(n-1) ``` Another use of conditional expressions is handling optional arguments. For example, here is the init method from GoodKangaroo (see Exercise 2): > 條件表達式還可以用于處理可選參數。例如下面就是練習2中 GoodKangaroo 類的 init 方法: ```Python def __init__(self, name, contents=None): self.name = name if contents == None: contents = [] self.pouch_contents = contents ``` We can rewrite this one like this: > 我們可以這樣來改寫: ```Python def __init__(self, name, contents=None): self.name = name self.pouch_contents = [] if contents == None else contents ``` In general, you can replace a conditional statement with a conditional expression if both branches contain simple expressions that are either returned or assigned to the same variable. > 一般來講,你可以用條件表達式來替換掉條件語句,無論這些語句的分支是返回語句或者是賦值語句。 ## 19.2 List comprehensions 列表推導 In Section 10.7 we saw the map and filter patterns. For example, this function takes a list of strings, maps the string method capitalize to the elements, and returns a new list of strings: > 在10.7當中,我們看到了映射和過濾模式。例如,下面這個函數接收一個字符串列表,然后將每一個元素都用字符串方法 capitalize 處理成大寫的,然后返回一個新的字符串列表: ```Python def capitalize_all(t): res = [] for s in t: res.append(s.capitalize()) return res ``` We can write this more concisely using a list comprehension: > 用列表推導就可以將上面的代碼寫得更簡潔: ```Python def capitalize_all(t): return [s.capitalize() for s in t] ``` The bracket operators indicate that we are constructing a new list. The expression inside the brackets specifies the elements of the list, and the for clause indicates what sequence we are traversing. > 方括號的意思是我們正在建立一個新的列表。方括號內的表達式確定了此新列表中的元素,然后 for 語句表明我們要遍歷的序列。 The syntax of a list comprehension is a little awkward because the loop variable, s in this example, appears in the expression before we get to the definition. > 列表推導的語法有點復雜,就因為這個循環變量,在上面例子中是 s,這個 s 在我們定義之前就出現在語句中了。 List comprehensions can also be used for filtering. For example, this function selects only the elements of t that are upper case, and returns a new list: > 列表推導也可以用到濾波中。例如,下面的函數從 t 中選擇了大寫的元素,然后返回成一個新的列表: ```Python def only_upper(t): res = [] for s in t: if s.isupper(): res.append(s) return res ``` We can rewrite it using a list comprehension: > 咱們可以用列表推導來重寫這個函數: ```Python def only_upper(t): return [s for s in t if s.isupper()] ``` List comprehensions are concise and easy to read, at least for simple expressions. And they are usually faster than the equivalent for loops, sometimes much faster. So if you are mad at me for not mentioning them earlier, I understand. > 列表推導很簡潔,也很容易閱讀,至少在簡單的表達式上是這樣。這些語句的執行也往往比同樣情況下的 for 循環更快一些,有時候甚至快很多。所以如果你因為我沒有早些給你講而發怒,我也能理解。 But, in my defense, list comprehensions are harder to debug because you can’t put a print statement inside the loop. I suggest that you use them only if the computation is simple enough that you are likely to get it right the first time. And for beginners that means never. > 但是,我也要辯護一下,列表推導會導致調試非常困難,因為你不能在循環內部放 print 語句了。我建議你只去在一些簡單的地方使用,要確保你第一次寫出來就能保證代碼正常工作。也就是說初學者就還是別用為好。 ## 19.3 Generator expressions 生成器表達式 Generator expressions are similar to list comprehensions, but with parentheses instead of square brackets: > 生成器表達式與列表推導相似,用的不是方括號,而是圓括號: ```Python >>> g = (x**2 for x in range(5)) >>> g = (x**2 for x in range(5)) >>> g >>> g <generator object <genexpr> at 0x7f4c45a786c0> ``` The result is a generator object that knows how to iterate through a sequence of values. But unlike a list comprehension, it does not compute the values all at once; it waits to be asked. The built-in function next gets the next value from the generator: > 上面這樣運行得到的結果就是一個生成器對象,用來遍歷一個值的序列。但與列表推導不同的是,生成器表達式并不會立即計算出所有的值;它要等著被調用。內置函數 next 會從生成器中得到下一個值: ```Python >>> next(g) >>> next(g) 0 >>> next(g) >>> next(g) 1 ``` When you get to the end of the sequence, next raises a StopIteration exception. You can also use a for loop to iterate through the values: > 當程序運行到序列末尾的時候,next 函數就會拋出一個停止遍歷的異常。你也可以用一個 for 循環來遍歷所有的值: ```Python >>> for val in g: ... >>> for val in g: ... print(val) 4 9 16 ``` The generator object keeps track of where it is in the sequence, so the for loop picks up where next left off. Once the generator is exhausted, it continues to raise StopException: > 生成器對象能夠追蹤在序列中的位置,所以 for 語句就會在 next 函數退出的地方開始。一旦生成器使用完畢了,接下來就要拋出一個停止異常了: ```Python >>> next(g) >>> next(g) StopIteration ``` Generator expressions are often used with functions like sum, max, and min: > 生成器表達式多用于求和、求最大或者最小這樣的函數中: ```Python >>> sum(x**2 for x in range(5)) >>> sum(x**2 for x in range(5)) 30 ``` ## 19.4 any and all 任意和所有 Python provides a built-in function, any, that takes a sequence of boolean values and returns True if any of the values are True. It works on lists: > Python 提供了一個名為 any 的內置函數,該函數接收一個布爾值序列,只要里面有任意一個是真,就返回真。該函數適用于列表: ```Python >>> any([False, False, True]) >>> any([False, False, True]) True ``` But it is often used with generator expressions: > 但這個函數多用于生成器表達式中: ```Python >>> any(letter == 't' for letter in 'monty') >>> any(letter == 't' for letter in 'monty') True ``` That example isn’t very useful because it does the same thing as the in operator. But we could use any to rewrite some of the search functions we wrote in Section 9.3. For example, we could write avoids like this: > 這個例子沒多大用,因為效果和 in 運算符是一樣的。但我們能用 any 函數來改寫我們在9.3中寫的一些搜索函數。例如,我們可以用如下的方式來改寫 avoids: ```Python def avoids(word, forbidden): return not any(letter in forbidden for letter in word) ``` The function almost reads like English, “word avoids forbidden if there are not any forbidden letters in word.” > 這樣這個函數讀起來基本就跟英語一樣了。 Using any with a generator expression is efficient because it stops immediately if it finds a True value, so it doesn’t have to evaluate the whole sequence. > 用 any 函數和生成器表達式來配合會很有效率,因為只要發現真值程序就會停止了,所以并不需要對整個序列進行運算。 Python provides another built-in function, all, that returns True if every element of the sequence is True. As an exercise, use all to re-write uses_all from Section 9.3. > Python 還提供了另外一個內置函數 all,該函數在整個序列都是真的情況下才返回真。 > 做個練習,用 all 來改寫一下9.3中的uses_all 函數。 ## 19.5 Sets 集合 In Section 13.6 I use dictionaries to find the words that appear in a document but not in a word list. The function I wrote takes d1, which contains the words from the document as keys, and d2, which contains the list of words. It returns a dictionary that contains the keys from d1 that are not in d2. > 在13.6中,我用了字典來查找存在于文檔中而不存在于詞匯列表中的詞匯。我寫的這個函數接收兩個參數,一個是 d1是包含了文檔中的詞作為鍵,另外一個是 d2包含了詞匯列表。程序會返回一個字典,這個字典包含的鍵存在于 d1而不在 d2中。 ```Python def subtract(d1, d2): res = dict() for key in d1: if key not in d2: res[key] = None return res ``` In all of these dictionaries, the values are None because we never use them. As a result, we waste some storage space. > 在這些字典中,鍵值都是 None,因為根本沒有使用。結果就是,浪費了一些存儲空間。 Python provides another built-in type, called a set, that behaves like a collection of dictionary keys with no values. Adding elements to a set is fast; so is checking membership. And sets provide methods and operators to compute common set operations. > Python 還提供了另一個內置類型,名為 set(也就是集合的意思),其性質就是有字典的鍵而無鍵值。 > 對集合中添加元素是很快的;對集合成員進行檢查也很快。此外集合還提供了一些方法和運算符來進行常見的集合運算。 For example, set subtraction is available as a method called difference or as an operator, -. So we can rewrite subtract like this: > 例如,集合的減法就可以用一個名為 difference 的方法,或者就用減號-。所以我們可以把 subtract 改寫成如下形式: ```Python def subtract(d1, d2): return set(d1) - set(d2) ``` The result is a set instead of a dictionary, but for operations like iteration, the behavior is the same. > 上面這個函數的結果就是一個集合而不是一個字典,但對于遍歷等等運算來說,用起來都一樣的。 Some of the exercises in this book can be done concisely and efficiently with sets. For example, here is a solution to has_duplicates, from Exercise 7, that uses a dictionary: > 本書中的一些練習都可以通過使用集合而改寫成更精簡更高效的形式。例如,下面的代碼就是 has_duplicates 的一個實現方案,來自練習7,用的是字典: ```Python def has_duplicates(t): d = {} for x in t: if x in d: return True d[x] = True return False ``` When an element appears for the first time, it is added to the dictionary. If the same element appears again, the function returns True. > 當一個元素第一次出現的時候,就被添加到字典中。如果同一個元素又出現了,該函數就返回真。 Using sets, we can write the same function like this: > 用集合的話,我們就能把該函數寫成如下形式: ```Python def has_duplicates(t): return len(set(t)) < len(t) ``` An element can only appear in a set once, so if an element in t appears more than once, the set will be smaller than t. If there are no duplicates, the set will be the same size as t. > 一個元素在一個集合中只能出現一次,所以如果一個元素在 t 中出現次數超過一次,集合會比 t 規模小一些。如果沒有重復,集合的規模就應該和 t 一樣大。 We can also use sets to do some of the exercises in Chapter 9. For example, here’s a version of uses_only with a loop: > 我們還能用集合來做一些第九章的練習。例如,下面就是用一個循環實現的一個版本的 uses_only: ```Python def uses_only(word, available): for letter in word: if letter not in available: return False return True ``` uses_only checks whether all letters in word are in available. We can rewrite it like this: > uses_only 會檢查 word 中的所有字母是否出現在 available 中。我們可以用如下方法重寫: ```Python def uses_only(word, available): return set(word) <= set(available) ``` The <= operator checks whether one set is a subset or another, including the possibility that they are equal, which is true if all the letters in word appear in available. As an exercise, rewrite avoids using sets. > 這里的<=運算符會檢查一個集合是否切另外一個集合的子集或者相等,如果 word 中所有的字符都出現在 available 中就返回真。 ## 19.6 Counters 計數器 A Counter is like a set, except that if an element appears more than once, the Counter keeps track of how many times it appears. If you are familiar with the mathematical idea of a multiset, a Counter is a natural way to represent a multiset. > 計數器跟集合相似,除了一點,就是如果計數器中元素出現的次數超過一次,計數器會記錄下出現的次數。如果你對數學上多重集的概念有所了解,就會知道計數器是一種對多重集的表示方式。 Counter is defined in a standard module called collections, so you have to import it. You can initialize a Counter with a string, list, or anything else that supports iteration: > 計數器定義在一個名為 collections 的標準模塊中,所以你必須先導入一下。你可以用字符串,列表或者任何支持遍歷的類型來初始化一個計數器: ```Python >>> from collections import Counter >>> from collections import Counter >>> count = Counter('parrot') >>> count = Counter('parrot') >>> count >>> count Counter({'r': 2, 't': 1, 'o': 1, 'p': 1, 'a': 1}) ``` Counters behave like dictionaries in many ways; they map from each key to the number of times it appears. As in dictionaries, the keys have to be hashable. > 計數器的用法與字典在很多方面都相似;二者都映射了每個鍵到出現的次數上。在字典中,鍵必須是散列的。 Unlike dictionaries, Counters don’t raise an exception if you access an element that doesn’t appear. Instead, they return 0: > 與字典不同的是,當你讀取一個不存在的元素的時候,計數器并不會拋出異常。相反的,這時候程序會返回0: ```Python >>> count['d'] >>> count['d'] 0 ``` We can use Counters to rewrite is_anagram from Exercise 6: > 我們可以用計數器來重寫一下練習6中的這個 is_anagram 函數: ```Python def is_anagram(word1, word2): return Counter(word1) == Counter(word2) ``` If two words are anagrams, they contain the same letters with the same counts, so their Counters are equivalent. Counters provide methods and operators to perform set-like operations, including addition, subtraction, union and intersection. And they provide an often-useful method, most_common, which returns a list of value-frequency pairs, sorted from most common to least: > 如果兩個單詞是換位詞,他們包含同樣個數的同樣字母,所以他們的計數器是相等的。 > 計數器提供了一些方法和運算器來運行類似集合的運算,包括加法,剪發,合并和交集等等。此外還提供了一個最常用的方法,most_common,該方法會返回一個由值-出現概率組成的數據對的列表,按照概率從高到低排列: ```Python >>> count = Counter('parrot') >>> count = Counter('parrot') >>> for val, freq in count.most_common(3): ... >>> for val, freq in count.most_common(3): ... print(val, freq) r 2 p 1 a 1 ``` ## 19.7 defaultdict 默認字典 The collections module also provides defaultdict, which is like a dictionary except that if you access a key that doesn’t exist, it can generate a new value on the fly. > collection 模塊還提供了一個默認字典,與普通字典的區別在于當你讀取一個不存在的鍵的時候,程序會添加上一個新值給這個鍵。 When you create a defaultdict, you provide a function that’s used to create new values. A function used to create objects is sometimes called a factory. The built-in functions that create lists, sets, and other types can be used as factories: > 當你創建一個默認字典的時候,就提供了一個能創建新值的函數。用來創建新對象的函數也被叫做工廠。內置的創建列表、集合以及其他類型的函數都可以被用作工廠: ```Python >>> from collections import defaultdict >>> from collections import defaultdict >>> d = defaultdict(list) >>> d = defaultdict(list) ``` Notice that the argument is list, which is a class object, not list(), which is a new list. The function you provide doesn’t get called unless you access a key that doesn’t exist. > 要注意到這里的參數是一個列表,是一個類的對象,而不是 list(),帶括號的就是一個新列表了。這個創建新值的函數只有當你試圖讀取一個不存在的鍵的時候才會被調用。 ```Python >>> t = d['new key'] >>> t = d['new key'] >>> t [] >>> t [] ``` The new list, which we’re calling t, is also added to the dictionary. So if we modify t, the change appears in d: > 新的這個我們稱之為 t 的列表,也會被添加到字典中。所以如果我們修改 t,這種修改也會在 d 中出現。 ```Python >>> t.append('new value') >>> t.append('new value') >>> d >>> d defaultdict(<class 'list'>, {'new key': ['new value']}) ``` If you are making a dictionary of lists, you can often write simpler code using defaultdict. In my solution to Exercise 2, which you can get from [Here](http://thinkpython2.com/code/anagram_sets.py), I make a dictionary that maps from a sorted string of letters to the list of words that can be spelled with those letters. For example, ’opst’ maps to the list [’opts’, ’post’, ’pots’, ’spot’, ’stop’, ’tops’]. > 所以如果你要用列表組成字典的話,你就可以多用默認字典來寫出更簡潔的代碼。你可以在[這里](http://thinkpython2.com/code/anagram_sets.py)下載我給練習2提供的樣例代碼,其中我建立了一個字典,字典中建立了從一個字母字符串到一個可以由這些字母拼成的單詞的映射。例如,『opst』就映射到了列表[’opts’, ’post’, ’pots’, ’spot’, ’stop’, ’tops’]。 Here’s the original code: > 下面就是原版的代碼: ```Python def all_anagrams(filename): d = {} for line in open(filename): word = line.strip().lower() t = signature(word) if t not in d: d[t] = [word] else: d[t].append(word) return d ``` This can be simplified using setdefault, which you might have used in Exercise 2: > 用默認集合就可以簡化一下,就如你在練習2中用過的那樣: ```Python def all_anagrams(filename): d = {} for line in open(filename): word = line.strip().lower() t = signature(word) d.setdefault(t, []).append(word) return d ``` This solution has the drawback that it makes a new list every time, regardless of whether it is needed. For lists, that’s no big deal, but if the factory function is complicated, it might be. > 這個代碼有一個不足,就是每次都要建立一個新列表,而不論是否需要創建。對于列表來說,這倒不要緊,不過如果工廠函數比較復雜的話,這就麻煩了。 We can avoid this problem and simplify the code using a defaultdict: > 這時候咱們就可以用默認字典來避免這個問題并且簡化代碼: ```Python def all_anagrams(filename): d = defaultdict(list) for line in open(filename): word = line.strip().lower() t = signature(word) d[t].append(word) return d ``` My solution to Exercise 3, which you can download from [Here](http://thinkpython2.com/code/PokerHandSoln.py), uses setdefault in the function has_straightflush. This solution has the drawback of creating a Hand object every time through the loop, whether it is needed or not. As an exercise, rewrite it using a defaultdict. > 你可以從[這里](http://thinkpython2.com/code/PokerHandSoln.py)下載我給練習3寫的樣例代碼,該代碼中在 has_straightflush函數用的是默認集合。這份代碼的不足就在于每次循環都要創建一個 Hand 對象,而不論是否必要。做個練習,用默認字典來該寫一下這個程序。 ## 19.8 Named tuples 命名元組 Many simple objects are basically collections of related values. For example, the Point object defined in Chapter 15 contains two numbers, x and y. When you define a class like this, you usually start with an init method and a str method: > 很多簡單的類就是一些相關值的集合。例如在15章中定義的 Point 類中就包含兩個數值,x 和 y。當你這樣定義一個類的時候,你通常要寫一個 init 方法和一個 str 方法: ```Python class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return '(%g, %g)' % (self.x, self.y) ``` This is a lot of code to convey a small amount of information. Python provides a more concise way to say the same thing: > 要傳達這么小規模的信息卻要用這么多代碼。Python 提供了一個更簡單的方式來做類似的事情: ```Python from collections import namedtuple Point = namedtuple('Point', ['x', 'y']) ``` The first argument is the name of the class you want to create. The second is a list of the attributes Point objects should have, as strings. The return value from named tuple is a class object: > 第一個參數是你要寫的類的名字。第二個是 Point 對象需要有的屬性列表,為字符串。命名元組返回的值是一個類的對象。 ```Python >>> Point >>> Point <class '__main__.Point'> ``` Point automatically provides methods like \_\_init\_\_ and \_\_str\_\_ so you don’t have to write them. To create a Point object, you use the Point class as a function: > Point 會自動提供諸如 \_\_init\_\_ 和 \_\_str\_\_ 之類的方法,所以就不用再去寫了。 > 要建立一個 Point 對象,你就可以用 Point 類作為一個函數用: ```Python >>> p = Point(1, 2) >>> p = Point(1, 2) >>> p >>> p Point(x=1, y=2) ``` The init method assigns the arguments to attributes using the names you provided. The str method prints a representation of the Point object and its attributes. You can access the elements of the named tuple by name: > init 方法把參數賦值給按照你設定來命名的屬性。 str 方法輸出整個 Point 類及其屬性的一個字符串表達。 > 你可以用名字來讀取命名元組中的元素: ```Python >>> p.x, p.y >>> p.x, p.y (1, 2) ``` But you can also treat a named tuple as a tuple: > 但你也可以把命名元組當做元組來用: ```Python >>> p[0], p[1] >>> p[0], p[1] (1, 2) >>> x, y = p >>> x, y = p >>> x, y >>> x, y (1, 2) ``` Named tuples provide a quick way to define simple classes. The drawback is that simple classes don’t always stay simple. You might decide later that you want to add methods to a named tuple. In that case, you could define a new class that inherits from the named tuple: > 命名元組提供了定義簡單類的快捷方式。缺點就是這些簡單的類不能總保持簡單的狀態。有時候你可能想給一個命名元組添加方法。這時候你就得定義一個新類來繼承命名元組: ```Python class Pointier(Point): # add more methods here ``` Or you could switch to a conventional class definition. > 或者你可以把命名元組轉換成一個常規的類的定義。 ## 19.9 Gathering keyword args 收集關鍵詞參數 In Section 12.4, we saw how to write a function that gathers its arguments into a tuple: > 在12.4中,我們已經學過了如何寫將參數收集到一個元組中的函數: ```Python def printall(*args): print(args) ``` You can call this function with any number of positional arguments (that is, arguments that don’t have keywords): > 這種函數可以用任意數量的位置參數(就是無關鍵詞的參數)來調用。 ```Python >>> printall(1, 2.0, '3') >>> printall(1, 2.0, '3') (1, 2.0, '3') ``` But the * operator doesn’t gather keyword arguments: > 但*運算符并不能收集關鍵詞參數: ```Python >>> printall(1, 2.0, third='3') >>> printall(1, 2.0, third='3') TypeError: printall() got an unexpected keyword argument 'third' ``` To gather keyword arguments, you can use the ** operator: > 要收集關鍵詞參數,你就可以用\*\*運算符: ```Python def printall(*args, **kwargs): print(args, kwargs) ``` You can call the keyword gathering parameter anything you want, but kwargs is a common choice. The result is a dictionary that maps keywords to values: > 你可以用任意名字來命名這里的關鍵詞收集參數,不過通常大家都用kwargs。得到的結果是一個字典,映射了關鍵詞鍵名與鍵值: ```Python >>> printall(1, 2.0, third='3') >>> printall(1, 2.0, third='3') (1, 2.0) {'third': '3'} ``` If you have a dictionary of keywords and values, you can use the scatter operator, ** to call a function: > 如果你有一個關鍵詞和值組成的字典,你就可以用散射運算符,\*\*來調用一個函數: ```Python >>> d = dict(x=1, y=2) >>> d = dict(x=1, y=2) >>> Point(**d) >>> Point(**d) Point(x=1, y=2) ``` Without the scatter operator, the function would treat d as a single positional argument, so it would assign d to x and complain because there’s nothing to assign to y: > 不用散射運算符的話,函數會把 d 當做一個單獨的位置參數,所以就會把 d 賦值股額 x,然后出錯,因為沒有給 y 賦值: ```Python >>> d = dict(x=1, y=2) >>> d = dict(x=1, y=2) >>> Point(d) >>> Point(d) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __new__() missing 1 required positional argument: 'y' ``` When you are working with functions that have a large number of parameters, it is often useful to create and pass around dictionaries that specify frequently-used options. > 當你寫一些有大量參數的函數的時候,就可以創建和使用一些字典,這樣能把各種常用選項弄清。 ## 19.10 Glossary 術語列表 conditional expression: An expression that has one of two values, depending on a condition. > 條件表達式:一種根據一個條件來從兩個值中選一個的表達式。 list comprehension: An expression with a for loop in square brackets that yields a new list. > 列表推導:一種用表達式, 方括號內有一個for 循環,生成一個新的列表。 generator expression: An expression with a for loop in parentheses that yields a generator object. > 生成器表達式:一種表達式,圓括號內放一個 for 循環,產生一個生成器對象。 multiset: A mathematical entity that represents a mapping between the elements of a set and the number of times they appear. > 多重集:一個數學上的概念,表示了一種從集合中元素到出現次數只見的映射關系。 factory: A function, usually passed as a parameter, used to create objects. > 工廠:一個函數,通常作為參數傳遞,用來產生對象。 ## 19.11 Exercises 練習 ### Exercise 1 練習1 The following is a function computes the binomial coefficient recursively. > 下面的函數是遞歸地計算二項式系數的。 ```Python def binomial_coeff(n, k): """Compute the binomial coefficient "n choose k". n: number of trials k: number of successes returns: int """ if k == 0: return 1 if n == 0: return 0 res = binomial_coeff(n-1, k) + binomial_coeff(n-1, k-1) return res ``` Rewrite the body of the function using nested conditional expressions. > 用網狀條件語句來重寫一下函數體。 One note: this function is not very efficient because it ends up computing the same values over and over. You could make it more efficient by memoizing (see Section 11.6). But you will find that it’s harder to memoize if you write it using conditional expressions. > 一點提示:這個函數并不是很有效率,因為總是要一遍一遍地計算同樣的值。你可以通過存儲已有結果(參考11.6)來提高效率。但你會發現如果你用條件表達式實現,就會導致這種記憶更困難。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看