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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # :-: python初識 [TOC] ## **數據類型** 1.整數 2.浮點數 3.字符串 4.布爾型 5.空值 注釋使用 # ## **變量** 變量名必須是大小寫英文、數字和下劃線的組合,且不能用數字開頭 ## **字符串** 字符串可以用`''`或者`""`括起來表示。 如果字符串本身包含`'`怎么辦?比如我們要表示字符串`?I'm OK?`,這時,可以用`" "`括起來表示: ~~~ "I'm OK" ~~~ 如果字符串既包含`'`又包含`"` 這個時候,就需要對字符串的某些特殊字符進行“轉義”,Python字符串用`\`進行轉義。 要表示字符串?`Bob said "I'm OK".` ~~~ 'Bob said \"I\'m OK\".' ~~~ 常用的轉義字符還有: ~~~ \n 表示換行 \t 表示一個制表符 \\ 表示 \ 字符本身 ~~~ ## **Python中raw字符串與多行字符串** 如果一個字符串包含很多需要轉義的字符,對每一個字符都進行轉義會很麻煩。為了避免這種情況,我們可以在字符串前面加個前綴`r`,表示這是一個?raw?字符串,里面的字符就不需要轉義了。例如: ~~~ r'\(~_~)/ \(~_~)/' ~~~ 但是`r'...'`表示法不能表示多行字符串,也不能表示包含`'`和`"`的字符串 如果要表示多行字符串,可以用`'''...'''`表示 ~~~ '''Line 1 Line 2 Line 3''' ~~~ 上面這個字符串的表示方法和下面的是完全一樣的: ``` 'Line 1\\nLine 2\\nLine 3' ``` 還可以在多行字符串前面添加`r`,把這個多行字符串也變成一個raw字符串: ~~~ r'''Python is created by "Guido". It is free and easy to learn. Let's start learn Python in imooc!''' ~~~ ## **Python中Unicode字符串** Python在后來添加了對Unicode的支持,以Unicode表示的字符串用u'...'表示,比如: ~~~ print u'中文' 中文 ~~~ Unicode字符串除了多了一個`u`之外,與普通字符串沒啥區別,轉義字符和多行表示法仍然有效 **多行:** ~~~ u'''第一行 第二行''' ~~~ **raw+多行:** ~~~ ur'''Python的Unicode字符串支持"中文", "日文", "韓文"等多種語言''' ~~~ 如果中文字符串在Python環境下遇到 UnicodeDecodeError,這是因為.py文件保存的格式有問題。可以在第一行添加注釋 ~~~ # -*- coding: utf-8 -*- ~~~ ## **Python中整數和浮點數** Python支持對整數和浮點數直接進行四則混合運算,運算規則和數學上的四則運算規則完全一致。 基本的運算: ~~~ 1 + 2 + 3 # ==> 6 4 * 5 - 6 # ==> 14 7.5 / 8 + 2.1 # ==> 3.0375 ~~~ 使用括號可以提升優先級,這和數學運算完全一致,注意只能使用小括號,但是括號可以嵌套很多層: ~~~ (1 + 2) * 3 # ==> 9 (2.2 + 3.3) / (1.5 * (9 - 0.3)) # ==> 0.42145593869731807 ~~~ 和數學運算不同的地方是,Python的整數運算結果仍然是整數,浮點數運算結果仍然是浮點數: ~~~ 1 + 2 # ==> 整數 3 1.0 + 2.0 # ==> 浮點數 3.0 ~~~ 但是整數和浮點數混合運算的結果就變成浮點數了: ~~~ 1 + 2.0 # ==> 浮點數 3.0 ~~~ > 為什么要區分整數運算和浮點數運算呢?這是因為整數運算的結果永遠是精確的,而浮點數運算的結果不一定精確,因為計算機內存再大,也無法精確表示出無限循環小數,比如`0.1`換成二進制表示就是無限循環小數。 那整數的除法運算遇到除不盡的時候,結果難道不是浮點數嗎?我們來試一下: ~~~ 11 / 4 # ==> 2 ~~~ 令很多初學者驚訝的是,Python的整數除法,即使除不盡,結果仍然是整數,余數直接被扔掉。不過,Python提供了一個求余的運算 % 可以計算余數: ~~~ 11 % 4 # ==> 3 ~~~ 如果我們要計算 11 / 4 的精確結果,按照“整數和浮點數混合運算的結果是浮點數”的法則,把兩個數中的一個變成浮點數再運算就沒問題了: ~~~ 11.0 / 4 # ==> 2.75 ~~~ ## **Python中布爾類型** **與運算**:只有兩個布爾值都為 True 時,計算結果才為 True。 ~~~ True and True # ==> True True and False # ==> False False and True # ==> False False and False # ==> False ~~~ **或運算**:只要有一個布爾值為 True,計算結果就是 True。 ~~~ True or True # ==> True True or False # ==> True False or True # ==> True False or False # ==> False ~~~ **非運算**:把True變為False,或者把False變為True: ~~~ not True # ==> False not False # ==> True ~~~ Python把`0`、`空字符串''`和`None`看成?False,其他數值和非空字符串都看成True ~~~ a = True print a and 'a=T' or 'a=F' ~~~ 計算結果不是布爾類型,而是字符串 'a=T' ## **Python創建list** Python內置的一種數據類型是列表:`list`。list是一種有序的集合,可以隨時添加和刪除其中的元素。 ~~~ >>> ['Michael', 'Bob', 'Tracy'] ['Michael', 'Bob', 'Tracy'] ~~~ list是數學意義上的有序集合,也就是說,list中的元素是按照順序排列的。 構造list非常簡單,按照上面的代碼,直接用`[ ]`把list的所有元素都括起來,就是一個list對象。通常,我們會把list賦值給一個變量,這樣,就可以通過變量來引用list: ~~~ >>> classmates = ['Michael', 'Bob', 'Tracy'] >>> classmates # 打印classmates變量的內容 ['Michael', 'Bob', 'Tracy'] ~~~ 由于Python是動態語言,所以list中包含的元素并不要求都必須是同一種數據類型,我們完全可以在list中包含各種數據: ~~~ >>> L = ['Michael', 100, True] ~~~ 一個元素也沒有的list,就是空list: ~~~ >>> empty_list = [] ~~~ ## **Python之倒序訪問list** ~~~ >>> L = ['Adam', 'Lisa', 'Bart'] ~~~ ~~~ >>> print L[-1] Bart ~~~ 倒數第二用 -2 表示,倒數第三用 -3 表示,倒數第四用 -4 表示 ~~~ >>> print L[-2] Lisa >>> print L[-3] Adam >>> print L[-4] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range ~~~ ## **Python之添加新元素** **append()**總是把新的元素添加到 list 的尾部。 ~~~ >>> L = ['Adam', 'Lisa', 'Bart'] >>> L.append('Paul') >>> print L ['Adam', 'Lisa', 'Bart', 'Paul'] ~~~ 用list的`insert()`方法,它接受兩個參數,第一個參數是索引號,第二個參數是待添加的新元素: ~~~ >>> L = ['Adam', 'Lisa', 'Bart'] >>> L.insert(0, 'Paul') >>> print L ['Paul', 'Adam', 'Lisa', 'Bart'] ~~~ **L.insert(0, 'Paul')**的意思是,'Paul'將被添加到索引為 0 的位置上(也就是第一個),而原來索引為 0 的Adam同學,以及后面的所有同學,都自動向后移動一位。 ## **Python從list刪除元素** ~~~ >>> L = ['Adam', 'Lisa', 'Bart', 'Paul'] >>> L.pop() 'Paul' >>> print L ['Adam', 'Lisa', 'Bart'] ~~~ **pop()**方法總是刪掉list的最后一個元素,并且它還返回這個元素,所以我們執行 L.pop() 后,會打印出 'Paul'。 要把Paul踢出list,我們就必須先定位Paul的位置。由于Paul的索引是2,因此,用`pop(2)`把Paul刪掉: ~~~ >>> L.pop(2) 'Paul' >>> print L ['Adam', 'Lisa', 'Bart'] ~~~ ## **Python之創建tuple** tuple是另一種有序的列表,中文翻譯為“?元組?”。tuple 和 list 非常類似,但是,tuple一旦創建完畢,就不能修改了。 ~~~ >>> t = ('Adam', 'Lisa', 'Bart') ~~~ 創建tuple和創建list唯一不同之處是用`( )`替代了`[ ]`。 現在,這個`t`就不能改變了,tuple沒有 append()方法,也沒有insert()和pop()方法。所以,新同學沒法直接往 tuple 中添加,老同學想退出 tuple 也不行。 獲取 tuple 元素的方式和 list 是一模一樣的,我們可以正常使用 t\[0\],t\[-1\]等索引方式訪問元素,但是不能賦值成別的元素 ## **Python之創建單元素tuple** 正是因為用()定義單元素的tuple有歧義,所以 Python 規定,單元素 tuple 要多加一個逗號“,” ~~~ >>> t = (1,) >>> print t (1,) ~~~ 多元素 tuple 加不加這個額外的“,”效果是一樣的 ~~~ >>> t = (1, 2, 3,) >>> print t (1, 2, 3) ~~~ ## **Python之“可變”的tuple** 前面我們看到了tuple一旦創建就不能修改。現在,我們來看一個“可變”的tuple: ~~~ >>> t = ('a', 'b', ['A', 'B']) ~~~ **注意**到 t 有 3 個元素:**'a','b'**和一個list:**\['A', 'B'\]**。list作為一個整體是tuple的第3個元素。list對象可以通過 t\[2\] 拿到: ~~~ >>> L = t[2] ~~~ ## **Python之if語句** ~~~ age = 20 if age >= 18: print 'your age is', age print 'adult' print 'END' ~~~ > **注意:** Python代碼的縮進規則。具有相同縮進的代碼被視為代碼塊,上面的3,4行 print 語句就構成一個代碼塊(但不包括第5行的print)。如果 if 語句判斷為 True,就會執行這個代碼塊。 > 縮進請嚴格按照Python的習慣寫法:4個空格,不要使用Tab,更不要混合Tab和空格,否則很容易造成因為縮進引起的語法錯誤。 > **注意**: if 語句后接表達式,然后用`:`表示代碼塊開始。 > 如果你在Python交互環境下敲代碼,還要特別留意縮進,并且退出縮進需要多敲一行回車: ## **Python之 if-else** 當?if?語句判斷表達式的結果為True時,就會執行 if 包含的代碼塊: ~~~ if age >= 18: print 'adult' ~~~ ~~~ if not age >= 18: print 'teenager' ~~~ ~~~ if age >= 18: print 'adult' else: print 'teenager' ~~~ ## **Python之 if-elif-else** ~~~ if age >= 18: print 'adult' else: if age >= 6: print 'teenager' else: if age >= 3: print 'kid' else: print 'baby' ~~~ ## **Python之 for循環** list或tuple可以表示一個有序集合。如果我們想依次訪問一個list中的每一個元素呢?比如 list: ~~~ L = ['Adam', 'Lisa', 'Bart'] for name in L: print name ~~~ > **注意:?**?name 這個變量是在 for 循環中定義的,意思是,依次取出list中的每一個元素,并把元素賦值給 name,然后執行for循環體(就是縮進的代碼塊)。 ## **Python之 while循環** 和 for 循環不同的另一種循環是while循環,while 循環不會迭代 list 或 tuple 的元素,而是根據表達式判斷循環是否結束。 比如要從 0 開始打印不大于 N 的整數: ~~~ N = 10 x = 0 while x < N: print x x = x + 1 ~~~ while循環每次先判斷 x < N,如果為True,則執行循環體的代碼塊,否則,退出循環。 在循環體內,x = x + 1會讓x不斷增加,最終因為x < N不成立而退出循環。 如果沒有這一個語句,**while循環在判斷 x < N 時總是為True**,就會無限循環下去,變成死循環,所以要特別留意while循環的退出條件 ## **Python之 break退出循環** 用 for 循環或者 while 循環時,如果要在循環體內直接退出循環,可以使用?break?語句。 比如計算1至100的整數和,我們用while來實現: ~~~ sum = 0 x = 1 while True: sum = sum + x x = x + 1 if x > 100: break print sum ~~~ ## **Python之 continue繼續循環** 在循環過程中,可以用break退出當前循環,還可以用continue跳過后續循環代碼,繼續下一次循環。 假設我們已經寫好了利用for循環計算平均分的代碼: ~~~ L = [75, 98, 59, 81, 66, 43, 69, 85] sum = 0.0 n = 0 for x in L: sum = sum + x n = n + 1 print sum / n ~~~ 現在老師只想統計及格分數的平均分,就要把 x < 60 的分數剔除掉,這時,利用 continue,可以做到當 x < 60的時候,不繼續執行循環體的后續代碼,直接進入下一次循環: ~~~ for x in L: if x < 60: continue sum = sum + x n = n + 1 ~~~ ## **Python之 多重循環** ~~~ for x in ['A', 'B', 'C']: for y in ['1', '2', '3']: print x + y ~~~ ## **Python之什么是dict** Python的 dict 就是專門干這件事的。用?**dict?**表示**“名字”-“成績”**的查找表如下: ~~~ d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } ~~~ 我們把**名字稱為key**,對應的**成績稱為value**,dict就是通過**key**來查找**value**。 花括號{}表示這是一個dict,然后按照**key: value**, 寫出來即可。最后一個 key: value 的逗號可以省略。 由于dict也是集合,len()?函數可以計算任意集合的大小: ~~~ >>> len(d) 3 ~~~ ## **Python之訪問dict** 可以簡單地使用d\[key\]的形式來查找對應的 value,這和 list 很像,不同之處是,**list 必須使用索引返回對應的元素,而dict使用key:** **注意:**通過 key 訪問 dict 的value,只要 key 存在,dict就返回對應的value。如果key不存在,會直接報錯:KeyError。 要避免 KeyError 發生,有兩個辦法: **一是先判斷一下 key 是否存在,用 in 操作符:** ~~~ if 'Paul' in d: print d['Paul'] ~~~ **二是使用dict本身提供的一個 get 方法,在Key不存在的時候,返回None:** ~~~ >>> print d.get('Bart') 59 >>> print d.get('Paul') None ~~~ ## **Python中dict的特點** **dict的第一個特點是查找速度快,無論dict有10個元素還是10萬個元素,查找速度都一樣**。而list的查找速度隨著元素增加而逐漸下降。 不過dict的查找速度快不是沒有代價的,**dict的缺點是占用內存大,還會浪費很多內容**,list正好相反,占用內存小,但是查找速度慢。 由于dict是按 key 查找,所以,在一個dict中,key不能重復。 **dict的第二個特點就是存儲的key-value序對是沒有順序的** **dict的第三個特點是作為 key 的元素必須不可變** ## **Python更新dict** dict是可變的,也就是說,我們可以隨時往dict中添加新的 key-value。比如已有dict: ~~~ d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } ~~~ 要把新同學'Paul'的成績 72 加進去,用賦值語句: ~~~ >>> d['Paul'] = 72 ~~~ 如果 key 已經存在,則賦值會用新的 value 替換掉原來的 value: ## **Python之 遍歷dict** 由于dict也是一個集合,所以,遍歷dict和遍歷list類似,都可以通過 for 循環實現。 直接使用for循環可以遍歷 dict 的 key: ~~~ >>> d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } >>> for key in d: ... print key ... Lisa Adam Bart ~~~ ## **Python中什么是set** **dict的作用是建立一組 key 和一組 value 的映射關系,dict的key是不能重復的。** 有的時候,我們只想要 dict 的 key,不關心 key 對應的 value,目的就是保證這個集合的元素不會重復,這時,set就派上用場了。 **set 持有一系列元素,這一點和 list 很像,但是set的元素沒有重復,而且是無序的,這點和 dict 的 key很像。** 創建 set 的方式是調用 set() 并傳入一個 list,list的元素將作為set的元素: ~~~ >>> s = set(['A', 'B', 'C']) ~~~ ~~~ >>> print s set(['A', 'C', 'B']) ~~~ **請注意**,上述打印的形式類似 list, 但它不是 list,仔細看還可以發現,打印的順序和原始 list 的順序有可能是不同的,因為set內部存儲的元素是**無序**的。 因為set不能包含重復的元素,所以,當我們傳入包含重復元素的 list 會怎么樣呢? ~~~ >>> s = set(['A', 'B', 'C', 'C']) >>> print s set(['A', 'C', 'B']) >>> len(s) 3 ~~~ ## **Python之 訪問set** 由于**set存儲的是無序集合**,所以我們沒法通過索引來訪問。 訪問 set中的某個元素實際上就是判斷一個元素是否在set中。 ~~~ >>> s = set(['Adam', 'Lisa', 'Bart', 'Paul']) ~~~ 我們可以用 in 操作符判斷 ~~~ >>> 'Bart' in s True ~~~ ~~~ >>> 'Bill' in s False ~~~ ~~~ >>> 'bart' in s False ~~~ 看來大小寫很重要,'Bart' 和 'bart'被認為是兩個不同的元素 ## **Python之 set的特點** **set的內部結構和dict很像,唯一區別是不存儲value**,因此,判斷一個元素是否在set中速度很快。 **set存儲的元素和dict的key類似,必須是不變對象**,因此,任何可變對象是不能放入set中的。 最后,set存儲的元素也是沒有順序的。 set的這些特點,可以應用在哪些地方呢? 星期一到星期日可以用字符串'MON', 'TUE', ... 'SUN'表示。 假設我們讓用戶輸入星期一至星期日的某天,如何判斷用戶的輸入是否是一個有效的星期呢? 可以用**if 語句**判斷,但這樣做非常繁瑣: ~~~ x = '???' # 用戶輸入的字符串 if x!= 'MON' and x!= 'TUE' and x!= 'WED' ... and x!= 'SUN': print 'input error' else: print 'input ok' ~~~ **注意:**if 語句中的...表示沒有列出的其它星期名稱,測試時,請輸入完整。 如果事先創建好一個set,包含'MON' ~ 'SUN': ~~~ weekdays = set(['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN']) ~~~ 再判斷輸入是否有效,只需要判斷該字符串是否在set中: ~~~ x = '???' # 用戶輸入的字符串 if x in weekdays: print 'input ok' else: print 'input error' ~~~ ## **Python之 遍歷set** 由于 set 也是一個集合,所以,遍歷 set 和遍歷 list 類似,都可以通過 for 循環實現。 直接使用 for 循環可以遍歷 set 的元素: ~~~ >>> s = set(['Adam', 'Lisa', 'Bart']) >>> for name in s: ... print name ... Lisa Adam Bart ~~~ **注意:?**觀察 for 循環在遍歷set時,元素的順序和list的順序很可能是不同的,而且不同的機器上運行的結果也可能不同。 ## **Python之 更新set** 由于**set存儲的是一組不重復的無序元素**,因此,更新set主要做兩件事: **一是把新的元素添加到set中,二是把已有元素從set中刪除。** 添加元素時,用set的add()方法: ~~~ >>> s = set([1, 2, 3]) >>> s.add(4) >>> print s set([1, 2, 3, 4]) ~~~ 如果添加的元素已經存在于set中,add()不會報錯,但是不會加進去了: ~~~ >>> s = set([1, 2, 3]) >>> s.add(3) >>> print s set([1, 2, 3]) ~~~ 刪除set中的元素時,用set的remove()方法: ~~~ >>> s = set([1, 2, 3, 4]) >>> s.remove(4) >>> print s set([1, 2, 3]) ~~~ 如果刪除的元素不存在set中,remove()會報錯: ~~~ >>> s = set([1, 2, 3]) >>> s.remove(4) Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 4 ~~~ 所以用add()可以直接添加,而remove()前需要判斷。 ## **Python之調用函數** Python內置了很多有用的函數,我們可以直接調用。 要調用一個函數,需要知道**函數**的**名稱**和**參數**,比如求絕對值的函數 abs,它接收一個參數。 ~~~ 可以直接從Python的官方網站查看文檔: http://docs.python.org/2/library/functions.html#abs ~~~ 也可以在交互式命令行通過help(abs)?查看abs函數的幫助信息。 調用?**abs?**函數: ~~~ >>> abs(100) 100 >>> abs(-20) 20 >>> abs(12.34) 12.34 ~~~ 調用函數的時候,如果傳入的參數數量不對,會報**TypeError**的錯誤,并且Python會明確地告訴你:abs()有且僅有1個參數,但給出了兩個: ~~~ >>> abs(1, 2) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: abs() takes exactly one argument (2 given) ~~~ 如果傳入的參數數量是對的,但參數類型不能被函數所接受,也會報**TypeError**的錯誤,并且給出錯誤信息:str是錯誤的參數類型: ~~~ >>> abs('a') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: bad operand type for abs(): 'str' ~~~ 而比較函數?cmp(x, y)?就需要兩個參數,如果**xy**,返回**1**: ~~~ >>> cmp(1, 2) -1 >>> cmp(2, 1) 1 >>> cmp(3, 3) 0 ~~~ Python內置的常用函數還包括數據類型轉換函數,比如? ?int()函數可以把其他數據類型轉換為整數: ~~~ >>> int('123') 123 >>> int(12.34) 12 ~~~ str()函數把其他類型轉換成 str: ~~~ >>> str(123) '123' >>> str(1.23) '1.23' ~~~ ## **Python之編寫函數** 在Python中,定義一個函數要使用**def**語句,依次寫出函數名、括號、括號中的參數和冒號:,然后,在縮進塊中編寫函數體,函數的返回值用?return語句返回。 我們以自定義一個求絕對值的 my\_abs 函數為例: ~~~ def my_abs(x): if x >= 0: return x else: return -x ~~~ **請注意**,函數體內部的語句在執行時,一旦執行到return時,函數就執行完畢,并將結果返回。因此,函數內部通過條件判斷和循環可以實現非常復雜的邏輯。 如果沒有return語句,函數執行完畢后也會返回結果,只是結果為 None。 return None可以簡寫為return。 ## **Python函數之返回多值** **\# math**包提供了**sin()**和?**cos()**函數,我們先用import引用它: ~~~ import math def move(x, y, step, angle): nx = x + step * math.cos(angle) ny = y - step * math.sin(angle) return nx, ny ~~~ 這樣我們就可以同時獲得返回值: ~~~ >>> x, y = move(100, 100, 60, math.pi / 6) >>> print x, y 151.961524227 70.0 ~~~ 但其實這只是一種假象,Python函數返回的仍然是單一值: ~~~ >>> r = move(100, 100, 60, math.pi / 6) >>> print r (151.96152422706632, 70.0) ~~~ 用print打印返回結果,原來返回值是一個**tuple**! 但是,在語法上,返回一個tuple可以省略括號,而多個變量可以同時接收一個tuple,按位置賦給對應的值,所以,**Python的函數**返回多值其實就是**返回一個tuple**,但寫起來更方便。 ## **Python之遞歸函數** 在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數。 舉個例子,我們來計算階乘**n! = 1 \* 2 \* 3 \* ... \* n**,用函數?**fact(n)**表示,可以看出: ~~~ fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n ~~~ 所以,**fact(n)**可以表示為**n \* fact(n-1)**,只有n=1時需要特殊處理。 于是,fact(n)用遞歸的方式寫出來就是: ~~~ def fact(n): if n==1: return 1 return n * fact(n - 1) ~~~ 遞歸函數的優點是定義簡單,邏輯清晰。理論上,所有的遞歸函數都可以寫成循環的方式,但循環的邏輯不如遞歸清晰 使用遞歸函數需要注意防止棧溢出。在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由于棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出。可以試試計算 fact(10000)。 ## **Python之定義默認參數** 例如Python自帶的**int()**函數,其實就有兩個參數,我們既可以傳一個參數,又可以傳兩個參數: ~~~ >>> int('123') 123 >>> int('123', 8) 83 ~~~ int()函數的第二個參數是轉換進制,如果不傳,默認是十進制 (base=10),如果傳了,就用傳入的參數。 可見,**函數的默認參數的作用是簡化調用**,你只需要把必須的參數傳進去。但是在需要的時候,又可以傳入額外的參數來覆蓋默認參數值。 我們來定義一個計算 x 的N次方的函數: ~~~ def power(x, n): s = 1 while n > 0: n = n - 1 s = s * x return s ~~~ 假設計算平方的次數最多,我們就可以把 n 的默認值設定為 2: ~~~ def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s ~~~ 這樣一來,計算平方就不需要傳入兩個參數了: ~~~ >>> power(5) 25 ~~~ 由于函數的參數按從左到右的順序匹配,所以**默認參數只能定義在必需參數的后面:** ## **Python之定義可變參數** 如果想讓一個函數能接受任意個參數,我們就可以定義一個可變參數: ~~~ def fn(*args): print args ~~~ 可變參數的名字前面有個?**\*?**號,我們可以傳入0個、1個或多個參數給可變參數: ~~~ >>> fn() () >>> fn('a') ('a',) >>> fn('a', 'b') ('a', 'b') >>> fn('a', 'b', 'c') ('a', 'b', 'c') ~~~ 可變參數也不是很神秘,Python解釋器會把傳入的一組參數組裝成一個tuple傳遞給可變參數,因此,在函數內部,直接把變量args看成一個?tuple?就好了。 定義可變參數的目的也是為了簡化調用。假設我們要計算任意個數的平均值,就可以定義一個可變參數: ~~~ def average(*args): ... ~~~ 這樣,在調用的時候,可以這樣寫: ~~~ >>> average() 0 >>> average(1, 2) 1.5 >>> average(1, 2, 2, 3, 4) 2.4 ~~~ ## **對list進行切片** 取一個list的部分元素是非常常見的操作。比如,一個list如下: ~~~ >>> L = ['Adam', 'Lisa', 'Bart', 'Paul'] ~~~ 取前3個元素,應該怎么做? 笨辦法: ~~~ >>> [L[0], L[1], L[2]] ['Adam', 'Lisa', 'Bart'] ~~~ 之所以是笨辦法是因為擴展一下,取前N個元素就沒轍了。 取前N個元素,也就是索引為0-(N-1)的元素,可以用循環: ~~~ >>> r = [] >>> n = 3 >>> for i in range(n): ... r.append(L[i]) ... >>> r ['Adam', 'Lisa', 'Bart'] ~~~ 對這種經常取指定索引范圍的操作,用循環十分繁瑣,因此,Python提供了切片(Slice)操作符,能大大簡化這種操作。 對應上面的問題,取前3個元素,用一行代碼就可以完成切片: ~~~ >>> L[0:3] ['Adam', 'Lisa', 'Bart'] ~~~ L\[0:3\]表示,從索引0開始取,直到索引3為止,但不包括索引3。即索引0,1,2,正好是3個元素。 如果第一個索引是0,還可以省略: ~~~ >>> L[:3] ['Adam', 'Lisa', 'Bart'] ~~~ 也可以從索引1開始,取出2個元素出來: ~~~ >>> L[1:3] ['Lisa', 'Bart'] ~~~ 只用一個**:**,表示從頭到尾: ~~~ >>> L[:] ['Adam', 'Lisa', 'Bart', 'Paul'] ~~~ 因此,L\[:\]實際上復制出了一個新list。 切片操作還可以指定第三個參數: ~~~ >>> L[::2] ['Adam', 'Bart'] ~~~ 第三個參數表示每N個取一個,上面的 L\[::2\] 會每兩個元素取出一個來,也就是隔一個取一個。 把list換成tuple,切片操作完全相同,只是切片的結果也變成了tuple。 ## **倒序切片** 對于list,既然Python支持L\[-1\]取倒數第一個元素,那么它同樣支持倒數切片,試試: ~~~ >>> L = ['Adam', 'Lisa', 'Bart', 'Paul'] >>> L[-2:] ['Bart', 'Paul'] >>> L[:-2] ['Adam', 'Lisa'] >>> L[-3:-1] ['Lisa', 'Bart'] >>> L[-4:-1:2] ['Adam', 'Bart'] ~~~ 記住倒數第一個元素的索引是-1。倒序切片包含起始索引,不包含結束索引。 ## **對字符串切片** 字符串 'xxx'和 Unicode字符串 u'xxx'也可以看成是一種list,每個元素就是一個字符。因此,字符串也可以用切片操作,只是操作結果仍是字符串: ~~~ >>> 'ABCDEFG'[:3] 'ABC' >>> 'ABCDEFG'[-3:] 'EFG' >>> 'ABCDEFG'[::2] 'ACEG' ~~~ 在很多編程語言中,針對字符串提供了很多各種截取函數,其實目的就是對字符串切片。Python沒有針對字符串的截取函數,只需要切片一個操作就可以完成,非常簡單。 ## **什么是迭代** 在Python中,如果給定一個**list**或**tuple**,我們可以通過for循環來遍歷這個list或tuple,這種遍歷我們成為迭代(Iteration)。 在Python中,迭代是通過?for ... in?來完成的,而很多語言比如C或者Java,迭代list是通過下標完成的,比如Java代碼: ~~~ for (i=0; i<list.length; i++) { n = list[i]; } ~~~ 可以看出,Python的for循環抽象程度要高于Java的for循環。 **因為 Python 的 for循環不僅可以用在list或tuple上,還可以作用在其他任何可迭代對象上。** 因此,迭代操作就是對于一個集合,無論該集合是有序還是無序,我們用 for 循環總是可以依次取出集合的每一個元素。 ~~~ 注意: 集合是指包含一組元素的數據結構,我們已經介紹的包括: 1. 有序集合:list,tuple,str和unicode; 2. 無序集合:set 3. 無序集合并且具有 key-value 對:dict ~~~ 而迭代是一個動詞,它指的是一種操作,在Python中,就是 for 循環。 迭代與按下標訪問數組最大的不同是,后者是一種具體的迭代實現方式,而前者只關心迭代結果,根本不關心迭代內部是如何實現的。 ## **索引迭代** Python中,**迭代永遠是取出元素本身,而非元素的索引。** 對于有序集合,元素確實是有索引的。有的時候,我們確實想在 for 循環中拿到索引,怎么辦? 方法是使用**enumerate() 函數**: ~~~ >>> L = ['Adam', 'Lisa', 'Bart', 'Paul'] >>> for index, name in enumerate(L): ... print index, '-', name ... 0 - Adam 1 - Lisa 2 - Bart 3 - Paul ~~~ 使用 enumerate() 函數,我們可以在for循環中同時綁定索引index和元素name。但是,這不是 enumerate() 的特殊語法。實際上,enumerate() 函數把: ~~~ ['Adam', 'Lisa', 'Bart', 'Paul'] ~~~ 變成了類似: ~~~ [(0, 'Adam'), (1, 'Lisa'), (2, 'Bart'), (3, 'Paul')] ~~~ 因此,迭代的每一個元素實際上是一個tuple: ~~~ for t in enumerate(L): index = t[0] name = t[1] print index, '-', name ~~~ 如果我們知道每個tuple元素都包含兩個元素,for循環又可以進一步簡寫為: ~~~ for index, name in enumerate(L): print index, '-', name ~~~ 這樣不但代碼更簡單,而且還少了兩條賦值語句。 可見,索引迭代也不是真的按索引訪問,而是由 enumerate() 函數自動把每個元素變成 (index, element) 這樣的tuple,再迭代,就同時獲得了索引和元素本身。 ## **迭代dict的value** 我們已經了解了**dict對象**本身就是可**迭代對象**,用 for 循環直接迭代 dict,可以每次拿到dict的一個key。 如果我們希望迭代 dict 對象的value,應該怎么做? dict 對象有一個**values() 方法**,這個方法把dict轉換成一個包含所有value的list,這樣,我們迭代的就是 dict的每一個 value: ~~~ d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } print d.values() # [85, 95, 59] for v in d.values(): print v # 85 # 95 # 59 ~~~ 如果仔細閱讀Python的文檔,還可以發現,dict除了**values()**方法外,還有一個**itervalues()**方法,用**itervalues()**方法替代**values()**方法,迭代效果完全一樣: ~~~ d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } print d.itervalues() # <dictionary-valueiterator object at 0x106adbb50> for v in d.itervalues(): print v # 85 # 95 # 59 ~~~ **那這兩個方法有何不同之處呢?** 1.**values()**方法實際上把一個 dict 轉換成了包含 value 的list。 2\. 但是**itervalues()**方法不會轉換,它會在迭代過程中依次從 dict 中取出 value,所以 itervalues() 方法比 values() 方法節省了生成 list 所需的內存。 3.?打印 itervalues() 發現它返回一個 對象,這說明在Python中,**for 循環可作用的迭代對象遠不止 list,tuple,str,unicode,dict等**,任何可迭代對象都可以作用于for循環,而內部如何迭代我們通常并不用關心。 **如果一個對象說自己可迭代,那我們就直接用 for 循環去迭代它,可見,迭代是一種抽象的數據操作,它不對迭代對象內部的數據有任何要求。** ## **迭代dict的key和value** 我們了解了如何**迭代 dict**的**key**和**value**,那么,在一個 for 循環中,能否同時迭代 key和value?答案是肯定的。 首先,我們看看 dict 對象的**items()**方法返回的值: ~~~ >>> d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } >>> print d.items() [('Lisa', 85), ('Adam', 95), ('Bart', 59)] ~~~ 可以看到,items() 方法把dict對象轉換成了包含tuple的list,我們對這個list進行迭代,可以同時獲得key和value: ~~~ >>> for key, value in d.items(): ... print key, ':', value ... Lisa : 85 Adam : 95 Bart : 59 ~~~ 和 values() 有一個 itervalues() 類似,**items()**也有一個對應的**iteritems()**,iteritems() 不把dict轉換成list,而是在迭代過程中不斷給出 tuple,所以, iteritems() 不占用額外的內存。 ## **生成列表** 要生成list \[1, 2, 3, 4, 5, 6, 7, 8, 9, 10\],我們可以用range(1, 11): ~~~ >>> range(1, 11) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ~~~ 但如果要生成\[1x1, 2x2, 3x3, ..., 10x10\]怎么做?方法一是循環: ~~~ >>> L = [] >>> for x in range(1, 11): ... L.append(x * x) ... >>> L [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ~~~ 但是循環太繁瑣,而列表生成式則可以用一行語句代替循環生成上面的list: ~~~ >>> [x * x for x in range(1, 11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ~~~ 這種寫法就是Python特有的列表生成式。利用列表生成式,可以以非常簡潔的代碼生成 list。 寫列表生成式時,把要生成的元素 x \* x 放到前面,后面跟 for 循環,就可以把list創建出來,十分有用,多寫幾次,很快就可以熟悉這種語法。 ## **復雜表達式** 使用**for循環**的迭代不僅可以迭代普通的list,還可以迭代dict。 假設有如下的dict: ~~~ d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } ~~~ 完全可以通過一個復雜的列表生成式把它變成一個 HTML 表格: ~~~ tds = ['<tr><td>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.iteritems()] print '<table>' print '<tr><th>Name</th><th>Score</th><tr>' print '\n'.join(tds) print '</table>' ~~~ **注:**字符串可以通過%進行格式化,用指定的參數替代%s。字符串的join()方法可以把一個 list 拼接成一個字符串。 把打印出來的結果保存為一個html文件,就可以在瀏覽器中看到效果了: ~~~ <table border="1"> <tr><th>Name</th><th>Score</th><tr> <tr><td>Lisa</td><td>85</td></tr> <tr><td>Adam</td><td>95</td></tr> <tr><td>Bart</td><td>59</td></tr> </table> ~~~ [![](http://img.mukewang.com/540fcd2a0001ff4600940104.jpg)](http://img.mukewang.com/540fcd2a0001ff4600940104.jpg) ## **條件過濾** 列表生成式的?**for 循環后面還可以加上 if 判斷**。例如: ~~~ >>> [x * x for x in range(1, 11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ~~~ 如果我們只想要偶數的平方,不改動 range()的情況下,可以加上 if 來篩選: ~~~ >>> [x * x for x in range(1, 11) if x % 2 == 0] [4, 16, 36, 64, 100] ~~~ 有了 if 條件,只有 if 判斷為 True 的時候,才把循環的當前元素添加到列表中。 ## **多層表達式** for循環可以嵌套,因此,在列表生成式中,也可以用多層for循環來生成列表。 對于字符串 'ABC' 和 '123',可以使用兩層循環,生成全排列: ~~~ >>> [m + n for m in 'ABC' for n in '123'] ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3'] ~~~ 翻譯成循環代碼就像下面這樣: ~~~ L = [] for m in 'ABC': for n in '123': L.append(m + n) ~~~
                  <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>

                              哎呀哎呀视频在线观看