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

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 1.2 Python語言 > 作者 Chris Burns, Christophe Combelles, Emmanuelle Gouillart, Gae?l Varoquaux > **Python中的科學計算** 這里我們介紹Python語言。這里只會僅僅解決可以用于Numpy和Scipy的最低要求。想要更多的了解這門語言,請參考[http://docs.python.org/tutorial](http://docs.python.org/tutorial) 這個非常好的教程。也可以借助專門的圖書,比如:[http://diveintopython.org/](http://diveintopython.org/). Python是一門**編程語言**,與C、Fortran、BASIC和PHP等等類似。Python的一些特性如下: * 一種_解釋性_(不是編譯)語言。與C或者Fortran等不同,Python代碼在執行前不會編譯。另外,Python可以**交互**使用:有許多的Python解釋器,命令和腳本可以在其中執行。 * 在**開源**證書下發布的免費軟件:Python可以免費使用和分發,即使用于商用。 * **多平臺**:Python可以用于所有的主流操作系統,Windows、Linux/Unix、MacOS X, 甚至可能是你有手機操作系統等等。 * 可讀性很強的語言,有清晰不羅嗦的語法 * 擁有大量高質量的包,可以應用于多種多樣的應用,從網站框架到科學計算。 * 非常簡單的接口與其他語言交互,特別是C和C++ * 稍后會介紹一些語言的其他特性。例如Python是面向對象的語言,包含動態類型(一個變量可以在程序過程中,可以包含不同的對象類型)。 Python的特有特性的更多信息,請見:[http://www.python.org/about/](http://www.python.org/about/) ## 1.2.1 第一步 啟動**IPython** Shell(一個增強的Python交互Shell): * 在Linux/Mac終端中輸入“ipython”,或者在Windows cmd sheell, * 或者從菜單啟動程序,即在[Python(x,y)](http://www.pythonxy.com/)或[EPD](http://www.enthought.com/products/epd.php),如果你已經安裝這些Python科學套裝之一。 如果你的電腦上還沒有安裝IPython,也可以選擇其他Python shells,比如在終端中輸入“Python”啟動純Python shell,或者Idle解釋器。但是,我們建議使用IPython Shell,因為它增強特性,特別是對于科學計算。 如果你已經啟動了解釋器,輸入 In?[2]: ``` print "Hello, world!" ``` ``` Hello, world! ``` 接下來就會顯示信息"Hello, world!"。你已經執行了你的第一條Python命令,恭喜! 你自己開始吧,輸入下列命令 In?[1]: ``` a = 3 b = 2*a type(b) ``` Out[1]: ``` int ``` In?[2]: ``` print b ``` ``` 6 ``` In?[3]: ``` a*b ``` Out[3]: ``` 18 ``` In?[4]: ``` b = 'hello' type(b) ``` Out[4]: ``` str ``` In?[5]: ``` b + b ``` Out[5]: ``` 'hellohello' ``` In?[6]: ``` 2*b ``` Out[6]: ``` 'hellohello' ``` 上面定義了_a_和_b_兩個變量。注意這里在賦值前沒有聲明變量類型。相反,在C中,應該寫為: ``` int a=3; ``` 另外,變量的類型可以改變,在一個時間點它可以等于一個特定類型,在接下來的時間里,他可以等于另外的類型。_b_首先等于整數,但是當它被賦值為_"hello"_時他變成等于字符。在Python中,整數的運算符(b=2*a)原生支持的,一些字符上的操作符例如相加和相乘也是支持的,相當于串聯和重復。 ## 1.2.2 基礎類型 ### 1.2.2.1 數值類型 Python支持如下的數值、標量類型: **整型:** In?[8]: ``` 1 + 1 ``` Out[8]: ``` 2 ``` In?[11]: ``` a = 4 type(a) ``` Out[11]: ``` int ``` **浮點型:** In?[12]: ``` c = 2.1 type(c) ``` Out[12]: ``` float ``` **復數:** In?[13]: ``` a = 1.5 + 0.5j a.real ``` Out[13]: ``` 1.5 ``` In?[14]: ``` a.imag ``` Out[14]: ``` 0.5 ``` In?[15]: ``` type(1. + 0j ) ``` Out[15]: ``` complex ``` **布爾:** In?[16]: ``` 3 > 4 ``` Out[16]: ``` False ``` In?[17]: ``` test = (3 > 4) test ``` Out[17]: ``` False ``` In?[18]: ``` type(test) ``` Out[18]: ``` bool ``` 因此,Python shell可以代替你的口袋計算器,因為基本的代數操作符 +、-、*、/、%(模)都已經原生實現了。 In?[19]: ``` 7 * 3. ``` Out[19]: ``` 21.0 ``` In?[20]: ``` 2**10 ``` Out[20]: ``` 1024 ``` In?[21]: ``` 8 % 3 ``` Out[21]: ``` 2 ``` 類型轉化(投射): In?[22]: ``` float(1) ``` Out[22]: ``` 1.0 ``` **注意**:整數相除 In?[23]: ``` 3 / 2 ``` Out[23]: ``` 1 ``` **技巧**:使用浮點: In?[24]: ``` 3 / 2. ``` Out[24]: ``` 1.5 ``` In?[25]: ``` a = 3 b = 2 a / b ``` Out[25]: ``` 1 ``` In?[26]: ``` a / float(b) ``` Out[26]: ``` 1.5 ``` 如果你明確想要整除,請使用//: In?[27]: ``` 3.0 // 2 ``` Out[27]: ``` 1.0 ``` Python3改變了除運算符行為。細節請看[python3porting](http://python3porting.com/preparing.html#use-instead-of-when-dividing-integers)網站. ### 1.2.2.2 容器 Python提供了許多有效的容器類型,其中存儲了對象集合。 #### 1.2.2.2.1 列表 列表是一個有序的對象集合,對象可以有多種類型。例如: In?[28]: ``` L = ['red', 'blue', 'green', 'black', 'white'] type(L) ``` Out[28]: ``` list ``` 索引:訪問包含在列表中的單個對象: In?[29]: ``` L[2] ``` Out[29]: ``` 'green' ``` 使用負索引,從結尾開始計數: In?[30]: ``` L[-1] ``` Out[30]: ``` 'white' ``` In?[31]: ``` L[-2] ``` Out[31]: ``` 'black' ``` **注意:索引從0開始**(和C中一樣),而不是1(像在Fortran或Matlab)! 切片:獲得規律分布元素的子列表: In?[32]: ``` L ``` Out[32]: ``` ['red', 'blue', 'green', 'black', 'white'] ``` In?[33]: ``` L[2:4] ``` Out[33]: ``` ['green', 'black'] ``` **注意**:L[start:stop]包含索引start&lt;= i &lt; stop的元素(i的范圍從start到stop-1)。因此,L[start:stop]包含(stop-start)個元素。 **切片語法**:`L[start:stop:stride]` 所有切片參數都是可選的: In?[34]: ``` L ``` Out[34]: ``` ['red', 'blue', 'green', 'black', 'white'] ``` In?[35]: ``` L[3:] ``` Out[35]: ``` ['black', 'white'] ``` In?[36]: ``` L[:3] ``` Out[36]: ``` ['red', 'blue', 'green'] ``` 列表是可變對象,可以被改變: In?[38]: ``` L[0] = 'yellow' L ``` Out[38]: ``` ['yellow', 'blue', 'green', 'black', 'white'] ``` In?[39]: ``` L[2:4] = ['gray', 'purple'] L ``` Out[39]: ``` ['yellow', 'blue', 'gray', 'purple', 'white'] ``` **注:**一個列表的元素可以有不同的類型: In?[40]: ``` L = [3, -200, 'hello'] L ``` Out[40]: ``` [3, -200, 'hello'] ``` In?[41]: ``` L[1], L[2] ``` Out[41]: ``` (-200, 'hello') ``` 對于一個所有類型都相同的數值數據集合,使用Numpy模塊提供的數組類型通常更有效。Numpy數組是包含固定大小項目的內存組塊。使用Numpy數組,元素上的操作可以非常快速,因為元素均勻分布在內存上并且更多的操作是通過特殊的C函數而不是Python循環。 Python提供了一大組函數來修改或查詢列表。這里是一些例子,更多內容,請見:[http://docs.python.org/tutorial/datastructures.html#more-on-lists](http://docs.python.org/tutorial/datastructures.html#more-on-lists) 添加和刪除元素: In?[42]: ``` L = ['red', 'blue', 'green', 'black', 'white'] L.append('pink') L ``` Out[42]: ``` ['red', 'blue', 'green', 'black', 'white', 'pink'] ``` In?[43]: ``` L.pop() # 刪除并返回最后一個項目 ``` Out[43]: ``` 'pink' ``` In?[44]: ``` L ``` Out[44]: ``` ['red', 'blue', 'green', 'black', 'white'] ``` In?[45]: ``` L.extend(['pink', 'purple']) # 擴展列表L,原地 L ``` In?[46]: ``` L = L[:-2] L ``` Out[46]: ``` ['red', 'blue', 'green', 'black', 'white'] ``` 反轉: In?[47]: ``` r = L[::-1] r ``` Out[47]: ``` ['white', 'black', 'green', 'blue', 'red'] ``` In?[48]: ``` r2 = list(L) r2 ``` Out[48]: ``` ['red', 'blue', 'green', 'black', 'white'] ``` In?[49]: ``` r2.reverse() # 原對象 r2 ``` Out[49]: ``` ['white', 'black', 'green', 'blue', 'red'] ``` 串聯和重復列表: In?[50]: ``` r + L ``` Out[50]: ``` ['white', 'black', 'green', 'blue', 'red', 'red', 'blue', 'green', 'black', 'white'] ``` In?[51]: ``` r * 2 ``` Out[51]: ``` ['white', 'black', 'green', 'blue', 'red', 'white', 'black', 'green', 'blue', 'red'] ``` 排序: In?[52]: ``` sorted(r) # 新對象 ``` Out[52]: ``` ['black', 'blue', 'green', 'red', 'white'] ``` In?[53]: ``` r ``` Out[53]: ``` ['white', 'black', 'green', 'blue', 'red'] ``` In?[55]: ``` r.sort() # 原對象 r ``` Out[55]: ``` ['black', 'blue', 'green', 'red', 'white'] ``` **方法和面向對象編程** 符號r.method() (即 r.append(3) and L.pop()) 是我們第一個關于面向對象編程的例子(OOP)。作為列表,對象r有可以以這種方式調用的方法函數。對于這篇教程不需要關于面向對象編程的更多知識,只需要理解這種符號。 **發現方法**: 提醒:在IPython中:tab完成 (按tab) ``` In [28]: r.<TAB> r.__add__ r.__iadd__ r.__setattr__ r.__class__ r.__imul__ r.__setitem__ r.__contains__ r.__init__ r.__setslice__ r.__delattr__ r.__iter__ r.__sizeof__ r.__delitem__ r.__le__ r.__str__ r.__delslice__ r.__len__ r.__subclasshook__ r.__doc__ r.__lt__ r.append r.__eq__ r.__mul__ r.count r.__format__ r.__ne__ r.extend r.__ge__ r.__new__ r.index r.__getattribute__ r.__reduce__ r.insert r.__getitem__ r.__reduce_ex__ r.pop r.__getslice__ r.__repr__ r.remove r.__gt__ r.__reversed__ r.reverse r.__hash__ r.__rmul__ r.sort ``` #### 1.2.2.2.2 字符 不同的字符語法(單引號、雙引號或三個引號): In?[58]: ``` s = 'Hello, how are you?' s = "Hi, what's up" s = '''Hello, how are you''' # 三個引號可以允許字符跨行 s = """Hi, what's up?""" 'Hi, what's up?' ``` ``` File "<ipython-input-58-dfe00f996c26>", line 7 'Hi, what's up?' ^ SyntaxError: invalid syntax ``` 如果在字符中要是使用引號,那么應該嵌套使用,或者使用"\"進行轉義,否則會報錯。 換行的符號為 \n,tab符號是\t。 字符也是類似與列表的結合。因此,也可以使用相同的語法和規則索引和切片。 索引: In?[59]: ``` a = "hello" a[0] ``` Out[59]: ``` 'h' ``` In?[60]: ``` a[1] ``` Out[60]: ``` 'e' ``` In?[61]: ``` a[-1] ``` Out[61]: ``` 'o' ``` (記住負索引從右側開始計數。) 切片: In?[64]: ``` a = "hello, world!" a[3:6] # 第三到第六個(不包含)元素:元素3、4、5 ``` Out[64]: ``` 'lo,' ``` In?[65]: ``` a[2:10:2] # 語法:a[開始:結束:步幅] ``` Out[65]: ``` 'lo o' ``` In?[66]: ``` a[::3] # 從開始到結尾,每隔3個字母 ``` Out[66]: ``` 'hl r!' ``` 重音符號和特殊字符也可以被處理為Unicode字符(請見 [http://docs.python.org/tutorial/introduction.html#unicode-strings)。](http://docs.python.org/tutorial/introduction.html#unicode-strings)。) 字符是**不可變**對象,不可能修改內容。不過可以從原始的字符中創建一個新的字符。 In?[68]: ``` a = "hello, world!" a[2] = 'z' ``` ``` --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-68-8f124c87c8cf> in <module>() 1 a = "hello, world!" ----> 2 a[2] = 'z' TypeError: 'str' object does not support item assignment ``` In?[69]: ``` a.replace('l', 'z', 1) ``` Out[69]: ``` 'hezlo, world!' ``` In?[70]: ``` a.replace('l', 'z') ``` Out[70]: ``` 'hezzo, worzd!' ``` 字符有許多有用的方法,比如上面的a.replace。回憶一下a.面向對象的符號,并且使用tab完成或者help(str)來搜索新的方法。and use tab completion or **更多內容** Python提供了操作的字符的高級可能性,看一下模式或格式。感興趣的讀者請參考:[http://docs.python.org/library/stdtypes.html#string-methods](http://docs.python.org/library/stdtypes.html#string-methods) 和 [http://docs.python.org/library/string.html#new-string-formatting。](http://docs.python.org/library/string.html#new-string-formatting。) 字符格式: In?[71]: ``` 'An integer: %i; a float: %f; another string: %s' % (1, 0.1, 'string') ``` Out[71]: ``` 'An integer: 1; a float: 0.100000; another string: string' ``` In?[72]: ``` i = 102 filename = 'processing_of_dataset_%d.txt' % i filename ``` Out[72]: ``` 'processing_of_dataset_102.txt' ``` #### 1.2.2.2.3\. Dictionaries 字典本質上是一個**映射鍵值**的高效表格。它是一個**無序**的容器 In?[74]: ``` tel = {'emmanuelle': 5752, 'sebastian': 5578} tel['francis'] = 5915 tel ``` Out[74]: ``` {'emmanuelle': 5752, 'francis': 5915, 'sebastian': 5578} ``` In?[75]: ``` tel['sebastian'] ``` Out[75]: ``` 5578 ``` In?[76]: ``` tel.keys() ``` Out[76]: ``` ['sebastian', 'francis', 'emmanuelle'] ``` In?[77]: ``` tel.values() ``` Out[77]: ``` [5578, 5915, 5752] ``` 它可以方便的以名字(日期的字符和名稱等)存儲和獲取值。更多信息見 [http://docs.python.org/tutorial/datastructures.html#dictionaries。](http://docs.python.org/tutorial/datastructures.html#dictionaries。) 一個字典的鍵(代表值)可以有不同的類型: In?[78]: ``` d = {'a':1, 'b':2, 3:'hello'} d ``` Out[78]: ``` {3: 'hello', 'a': 1, 'b': 2} ``` #### 1.2.2.2.4\. More container types **元組** 元組本質上是不可變列表。元組的元素用括號包起來,或者只是用逗號分割: In?[79]: ``` t = 12345, 54321, 'hello!' t[0] ``` Out[79]: ``` 12345 ``` In?[80]: ``` t ``` Out[80]: ``` (12345, 54321, 'hello!') ``` In?[81]: ``` u = (0, 2) ``` **集合**:無序,惟一項目: In?[82]: ``` s = set(('a', 'b', 'c', 'a')) s ``` Out[82]: ``` {'a', 'b', 'c'} ``` In?[83]: ``` s.difference(('a', 'b')) ``` Out[83]: ``` {'c'} ``` #### 1.2.2.3\. 賦值運算 [Python類庫參考:](http://docs.python.org/reference/simple_stmts.html#assignment-statements) > 賦值語句被用于(重)綁定名稱與值,以及修改可變對象的項目或屬性。 簡單來說,它這樣工作(簡單賦值): 1. 右側表達式被評估,創建或獲得產生的對象 2. 左側的名字被賦值或綁定到右側的對象 需要注意的事情: * 單個對象可以有多個綁定的名稱: In?[84]: ``` a = [1, 2, 3] b = a a ``` Out[84]: ``` [1, 2, 3] ``` In?[85]: ``` b ``` Out[85]: ``` [1, 2, 3] ``` In?[86]: ``` a is b ``` Out[86]: ``` True ``` In?[87]: ``` b[1] = 'hi!' a ``` Out[87]: ``` [1, 'hi!', 3] ``` * 要在**原地**改變列表,請使用索引或切片: In?[88]: ``` a = [1, 2, 3] a ``` Out[88]: ``` [1, 2, 3] ``` In?[89]: ``` a = ['a', 'b', 'c'] # 創建另一個對象 a ``` Out[89]: ``` ['a', 'b', 'c'] ``` In?[90]: ``` id(a) ``` Out[90]: ``` 4394695640 ``` In?[91]: ``` a[:] = [1, 2, 3] # 在原地修改對象 a ``` Out[91]: ``` [1, 2, 3] ``` In?[92]: ``` id(a) ``` Out[92]: ``` 4394695640 ``` 與上一個id相同,你的可能有所不同... * 這里的關鍵觀點是可變 vs. 不可變 * 可變對象可以在原地修改 * 不可變對象一旦被創建就不可修改 **更多內容**在David M. Beazley的文章[Python中的類型和對象](http://www.informit.com/articles/article.aspx?p=453682)中也可以找到關于以上問題非常不錯的詳盡解釋。 ## 1.2.3 流程控制 控制代碼執行順序。 ### 1.2.3.1 if/elif/else In?[93]: ``` if 2**2 == 4: print 'Obvious!' ``` ``` Obvious! ``` **代碼塊用縮進限定** **小技巧**:在你的Python解釋器內輸入下列行,并且注意保持縮進深度。IPython shell會在一行的 : 符號后自動增加縮進,如果要減少縮進,向左側移動4個空格使用后退鍵。按兩次回車鍵離開邏輯塊。 In?[96]: ``` a = 10 if a == 1: print(1) elif a == 2: print(2) else: print('A lot') ``` ``` A lot ``` 在腳本中也是強制縮進的。作為練習,在condition.py腳本中以相同的縮進重新輸入之前幾行,并在IPython中用`run condition.py`執行腳本。 ### 1.2.3.2 for/range 在索引上迭代: In?[97]: ``` for i in range(4): print(i) ``` ``` 0 1 2 3 ``` 但是最經常使用,也更易讀的是在值上迭代: In?[98]: ``` for word in ('cool', 'powerful', 'readable'): print('Python is %s' % word) ``` ``` Python is cool Python is powerful Python is readable ``` ### 1.2.3.3 while/break/continue 典型的C式While循環(Mandelbrot問題): In?[13]: ``` z = 1 + 1j while abs(z) < 100: z = z**2 + 1 z ``` Out[13]: ``` (-134+352j) ``` **更高級的功能** bread 跳出for/while循環: In?[103]: ``` z = 1 + 1j while abs(z) < 100: if z.imag == 0: break z = z**2 + 1 print z ``` ``` (1+2j) (-2+4j) (-11-16j) (-134+352j) ``` continue 繼續下一個循環迭代: In?[101]: ``` a = [1, 0, 2, 4] for element in a: if element == 0: continue print 1. / element ``` ``` 1.0 0.5 0.25 ``` ### 1.2.3.4 條件表達式 **if [OBJECT]:** 評估為False: ``` - 任何等于0的數字 (0、0.0、0+0j) - 空容器(列表、元組、集合、字典, ...) - False,None ``` 評估為True: ``` - 任何其他的東西 ``` **a == b:** 判斷邏輯是否相等: In?[1]: ``` 1 == 1 ``` Out[1]: ``` True ``` **a is b:** 測試同一性:兩邊是相同的對象: In?[2]: ``` 1 is 1 ``` Out[2]: ``` True ``` In?[3]: ``` a = 1 b = 1 a is b ``` Out[3]: ``` True ``` **a in b:** 對于任何集合b:b包含a In?[11]: ``` b = [1, 2, 3] 2 in b ``` Out[11]: ``` True ``` In?[12]: ``` 5 in b ``` Out[12]: ``` False ``` 如果b是字典,這個語法測試a是否是b的一個鍵。 ### 1.2.3.5\. 高級循環 #### 1.2.3.5.1 序列循環 你可以在任何序列上進行循環(字符、列表、字典的鍵,文件的行...): In?[14]: ``` vowels = 'aeiouy' for i in 'powerful': if i in vowels: print(i), ``` ``` o e u ``` In?[15]: ``` message = "Hello how are you?" message.split() # 返回一個列表 ``` Out[15]: ``` ['Hello', 'how', 'are', 'you?'] ``` In?[16]: ``` for word in message.split(): print word ``` ``` Hello how are you? ``` 很少有語言(特別是科學計算語言)允許在整數或索引之外的循環。在Python中,可以在感興趣的對象上循環,而不用擔心你通常不關心的索引。這個功能通常用來讓代碼更易讀。 **警告**:改變正在循環的序列是不安全的。 #### 1.2.3.5.2 跟蹤列舉數 通常任務是在一個序列上循環,同時跟蹤項目數。 ``` - 可以像上面,使用帶有計數器的while循環。或者一個for循環: ``` In?[17]: ``` words = ('cool', 'powerful', 'readable') for i in range(0, len(words)): print i, words[i] ``` ``` 0 cool 1 powerful 2 readable ``` 但是,Python為這種情況提供了enumerate關鍵詞: In?[18]: ``` for index, item in enumerate(words): print index, item ``` ``` 0 cool 1 powerful 2 readable ``` #### 1.2.3.5.3 字典循環 使用**iteritems**: In?[19]: ``` d = {'a': 1, 'b':1.2, 'c':1j} for key, val in d.iteritems(): print('Key: %s has value: %s' % (key, val)) ``` ``` Key: a has value: 1 Key: c has value: 1j Key: b has value: 1.2 ``` #### 1.2.3.5.4 列表理解 In?[20]: ``` [i**2 for i in range(4)] ``` Out[20]: ``` [0, 1, 4, 9] ``` **練習** 用Wallis公式,計算π的小數 ![Wallis公式](http://scipy-lectures.github.io/_images/math/31913b3982be13ed2063b0ffccbcab9cf4931fdb.png) ## 1.2.4\. 定義函數 ### 1.2.4.1 函數的定義 In?[21]: ``` def test(): print('in test function') test() ``` ``` in test function ``` **注意**:函數塊必須像其他流程控制塊一樣縮進 ### 1.2.4.2 返回語句 函數**可以選擇**返回值。 In?[22]: ``` def disk_area(radius): return 3.14 * radius * radius disk_area(1.5) ``` Out[22]: ``` 7.0649999999999995 ``` **注意**:默認函數返回`None`。 **注意**:注意定義函數的語法: * def關鍵字: * 接下來是函數的名稱,然后 * 在冒號后是在括號中的函數的參數。 * 函數體; * 以及可選返回值的返回對象 ### 1.2.4.3 參數 必選參數(位置參數) In?[24]: ``` def double_it(x): return x * 2 double_it(3) ``` Out[24]: ``` 6 ``` In?[25]: ``` double_it() ``` ``` --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-25-51cdedbb81b0> in <module>() ----> 1 double_it() TypeError: double_it() takes exactly 1 argument (0 given) ``` 可選參數(關鍵詞和命名參數) In?[26]: ``` def double_it(x=2): return x * 2 double_it() ``` Out[26]: ``` 4 ``` In?[27]: ``` double_it(3) ``` Out[27]: ``` 6 ``` 關鍵詞參數允許你設置特定默認值。 **警告:**默認值在函數定義時被評估,而不是在調用時。如果使用可變類型(即字典或列表)并在函數體內修改他們,這可能會產生問題,因為這個修改會在函數被引用的時候一直持續存在。 在關鍵詞參數中使用不可變類型: In?[2]: ``` bigx = 10 def double_it(x=bigx): return x * 2 bigx = 1e9 # 現在真的非常大 double_it() ``` Out[2]: ``` 20 ``` 在關鍵詞參數中使用可變類型(并且在函數體內修改它): In?[3]: ``` def add_to_dict(args={'a': 1, 'b': 2}): for i in args.keys(): args[i] += 1 print args add_to_dict ``` Out[3]: ``` <function __main__.add_to_dict> ``` In?[4]: ``` add_to_dict() ``` ``` {'a': 2, 'b': 3} ``` In?[5]: ``` add_to_dict() ``` ``` {'a': 3, 'b': 4} ``` In?[6]: ``` add_to_dict() ``` ``` {'a': 4, 'b': 5} ``` 更復雜的例子,實現Python的切片: In?[7]: ``` def slicer(seq, start=None, stop=None, step=None): """Implement basic python slicing.""" return seq[start:stop:step] rhyme = 'one fish, two fish, red fish, blue fish'.split() rhyme ``` Out[7]: ``` ['one', 'fish,', 'two', 'fish,', 'red', 'fish,', 'blue', 'fish'] ``` In?[8]: ``` slicer(rhyme) ``` Out[8]: ``` ['one', 'fish,', 'two', 'fish,', 'red', 'fish,', 'blue', 'fish'] ``` In?[9]: ``` slicer(rhyme, step=2) ``` Out[9]: ``` ['one', 'two', 'red', 'blue'] ``` In?[10]: ``` slicer(rhyme, 1, step=2) ``` Out[10]: ``` ['fish,', 'fish,', 'fish,', 'fish'] ``` In?[11]: ``` slicer(rhyme, start=1, stop=4, step=2) ``` Out[11]: ``` ['fish,', 'fish,'] ``` 關鍵詞參數的順序**不**重要: In?[12]: ``` slicer(rhyme, step=2, start=1, stop=4) ``` Out[12]: ``` ['fish,', 'fish,'] ``` 但是,最好是使用與函數定義相同的順序。 _關鍵詞參數_是特別方便的功能,可以用可變數量的參數來定義一個函數,特別是當函數據絕大多數調用都會使用默認值時。 ### 1.2.4.4 值傳遞 可以在一個函數內部改變變量的值嗎?大多數語言(C、Java...)區分了“值傳遞“和”引用傳遞“。在Python中,沒有嚴格的這種區分,并且視你的變量是否會修改而有一些不同。幸運的是,這些情況存在明確的規則。 函數的參數是對象的引用,傳遞的是值。當你像一個函數傳遞了一個變量,Python傳遞的是對象的引用,這個對象引用的變量(值)。而不是變量本身。 如果**值**傳遞給函數的值是不可變的,那么這個函數并不會改變調用者的變量。如果**值**是可變的,那么函數將可能在原地修改調用者的變量。 In?[13]: ``` def try_to_modify(x, y, z): x = 23 y.append(42) z = [99] # 新引用 print(x) print(y) print(z) a = 77 # 不可變變量 b = [99] # 可變變量 c = [28] try_to_modify(a, b, c) ``` ``` 23 [99, 42] [99] ``` In?[14]: ``` print(a) ``` ``` 77 ``` In?[15]: ``` print(b) ``` ``` [99, 42] ``` In?[16]: ``` print(c) ``` ``` [28] ``` 函數有名為_local namespace_的本地變量表。 變量X只存在于函數try_to_modify內部。 ### 1.2.4.5 全局變量 在函數外定義的變量可以在函數內引用: In?[18]: ``` x = 5 def addx(y): return x + y addx(10) ``` Out[18]: ``` 15 ``` 但是,這些全局變量不能在函數內修改,除非在函數內聲明**global**。 這樣沒用: In?[19]: ``` def setx(y): x = y print('x is %d' % x) setx(10) ``` ``` x is 10 ``` In?[20]: ``` x ``` Out[20]: ``` 5 ``` 這樣可以: In?[21]: ``` def setx(y): global x x = y print('x is %d' % x) setx(10) ``` ``` x is 10 ``` In?[22]: ``` x ``` Out[22]: ``` 10 ``` ### 1.2.4.6 可變數量參數 函數的特殊形式: ``` - *args:封裝成元組的任意數量的位置參數 - **kwargs:封裝成字典的任意數量的關鍵詞參數 ``` In?[23]: ``` def variable_args(*args, **kwargs): print 'args is', args print 'kwargs is', kwargs variable_args('one', 'two', x=1, y=2, z=3) ``` ``` args is ('one', 'two') kwargs is {'y': 2, 'x': 1, 'z': 3} ``` ### 1.2.4.7 Docstrings 關于函數作用及參數的文檔。通常慣例: In?[24]: ``` def funcname(params): """Concise one-line sentence describing the function. Extended summary which can contain multiple paragraphs. """ # 函數體 pass funcname? ``` ``` Type: function Base Class: type 'function'> String Form: <function funcname at 0xeaa0f0> Namespace: Interactive File: <ipython console> Definition: funcname(params) Docstring: Concise one-line sentence describing the function. Extended summary which can contain multiple paragraphs. ``` **注 Docstring 指導** 為了標準化,Docstring 慣例頁面為Python Docstring相關的含義及慣例提供了文檔。 Numpy和Scipy模塊也為科學計算函數定義了清晰的標準,你可能想要在自己的函數中去遵循,這個標準有參數部分,例子部分等。見[http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard](http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard) 及 [http://projects.scipy.org/numpy/browser/trunk/doc/example.py#L37](http://projects.scipy.org/numpy/browser/trunk/doc/example.py#L37) ### 1.2.4.8 函數作為對象 函數是一級對象,這意味著他們可以是: ``` - 可以被賦值給變量 - 列表的一個項目(或任何集合) - 作為參數傳遞給另一個函數 ``` In?[26]: ``` va = variable_args va('three', x=1, y=2) ``` ``` args is ('three',) kwargs is {'y': 2, 'x': 1} ``` ### 1.2.4.9 方法 方法是對象的函數。你已經在我們關于列表、字典和字符等...的例子上看到了。 ### 1.2.4.10\. 練習 **練習:斐波那契數列** 寫一個函數來展示斐波那契數列的前n個項目,定義如下: ``` - u_0 = 1; u_1 = 1 - u_(n+2) = u_(n+1) + u_n ``` **練習:快速排序** 實現快速排序算法,定義來自wikipedia: function quicksort(array) ``` var list less, greater if length(array) < 2 return array select and remove a pivot value pivot from array for each x in array if x < pivot + 1 then append x to less else append x to greater return concatenate(quicksort(less), pivot, quicksort(greater)) ```
                  <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>

                              哎呀哎呀视频在线观看