遞歸函數 ------- 在函數内部可以調用自身本身的函數
定義一個計算階乘的函數fact(n):
1
2
3
4
<code>fact(n) </code><code>=</code> <code>n!</code>
<code> </code><code>=</code> <code>1</code> <code>x </code><code>2</code> <code>x </code><code>3</code> <code>x ... x (n</code><code>-</code><code>1</code><code>) x n</code>
<code> </code><code>=</code> <code>(n</code><code>-</code><code>1</code><code>)! x n</code>
<code> </code><code>=</code> <code>fact(n</code><code>-</code><code>1</code><code>) x n</code>
函數可以寫為:
5
6
7
8
9
10
11
12
<code>>>> </code><code>def</code> <code>fact(n): </code>
<code> </code><code>if</code> <code>n</code><code>=</code><code>=</code><code>1</code><code>: </code>
<code> </code><code>return</code> <code>1</code>
<code> </code><code>return</code> <code>n</code><code>*</code><code>fact(n</code><code>-</code><code>1</code><code>)</code>
<code>>>> fact(</code><code>1</code><code>)</code>
<code>1</code>
<code>>>>fact(</code><code>5</code><code>)</code>
<code>120</code>
<code>>>> fact(</code><code>100</code><code>)</code>
<code>93326215443944152681699238856266700490715968264381621</code>
<code>46859296389521759999322991560894146397615651828625369</code>
<code>7920827223758251185210916864000000000000000000000000</code>
如果我們計算 <code>fact(5)</code>,可以根據函數定義看到計算過程如下:
<code>=</code><code>=</code><code>=</code><code>> fact(</code><code>5</code><code>)</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>5</code> <code>*</code> <code>fact(</code><code>4</code><code>)</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>5</code> <code>*</code> <code>(</code><code>4</code> <code>*</code> <code>fact(</code><code>3</code><code>))</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>5</code> <code>*</code> <code>(</code><code>4</code> <code>*</code> <code>(</code><code>3</code> <code>*</code> <code>fact(</code><code>2</code><code>)))</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>5</code> <code>*</code> <code>(</code><code>4</code> <code>*</code> <code>(</code><code>3</code> <code>*</code> <code>(</code><code>2</code> <code>*</code> <code>fact(</code><code>1</code><code>))))</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>5</code> <code>*</code> <code>(</code><code>4</code> <code>*</code> <code>(</code><code>3</code> <code>*</code> <code>(</code><code>2</code> <code>*</code> <code>1</code><code>)))</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>5</code> <code>*</code> <code>(</code><code>4</code> <code>*</code> <code>(</code><code>3</code> <code>*</code> <code>2</code><code>))</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>5</code> <code>*</code> <code>(</code><code>4</code> <code>*</code> <code>6</code><code>)</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>5</code> <code>*</code> <code>24</code>
<code>=</code><code>=</code><code>=</code><code>> </code><code>120</code>
遞歸函數的優點是定義簡單,邏輯清晰。理論上,所有的遞歸函數都可以寫成循環的方式,但循環的邏輯不如遞歸清晰。
使用遞歸函數需要注意防止棧溢出。在計算機中,函數調用是通過棧(stack)這種資料結構實作的,每當進入一個函數調用,棧就會加一層棧幀,每當函數傳回,棧就會減一層棧幀。由于棧的大小不是無限的,是以,遞歸調用的次數過多,會導緻棧溢出。可以試試<code>fact(1000)</code>:
13
14
15
16
<code>>>> fact(</code><code>1000</code><code>)</code>
<code>Traceback (most recent call last):</code>
<code> </code><code>File</code> <code>"<pyshell#40>"</code><code>, line </code><code>1</code><code>, </code><code>in</code> <code><module></code>
<code> </code><code>fact(</code><code>1000</code><code>) </code>
<code> </code><code>File</code> <code>"<pyshell#33>"</code><code>, line </code><code>4</code><code>, </code><code>in</code> <code>fact</code>
<code> </code><code>return</code> <code>n</code><code>*</code><code>fact(n</code><code>-</code><code>1</code><code>)</code>
<code> </code><code>return</code> <code>n</code><code>*</code><code>fact(n</code><code>-</code><code>1</code><code>) </code>
<code> </code><code>return</code> <code>n</code><code>*</code><code>fact(n</code><code>-</code><code>1</code><code>)</code>
<code> </code><code>。。。</code>
<code> </code><code>File</code> <code>"<pyshell#33>"</code><code>, line </code><code>4</code><code>, </code><code>in</code> <code>fact</code>
<code> </code><code>File</code> <code>"<pyshell#33>"</code><code>, line </code><code>2</code><code>, </code><code>in</code> <code>fact</code>
<code> </code><code>if</code> <code>n</code><code>=</code><code>=</code><code>1</code><code>:</code>
<code>RuntimeError: maximum recursion depth exceeded </code><code>in</code> <code>comparison</code>
切片
取一個list或tuple的部分元素:
(1):
直接通過索引取值
<code>>>> l</code><code>=</code><code>[</code><code>'xaioming'</code><code>,</code><code>'zhangsan'</code><code>,</code><code>'wangwu'</code><code>,</code><code>'xiaoxin'</code><code>,</code><code>'xaiohua'</code><code>]</code>
<code>>>> [l[</code><code>0</code><code>],l[</code><code>1</code><code>],l[</code><code>2</code><code>]]</code>
<code>[</code><code>'xaioming'</code><code>, </code><code>'zhangsan'</code><code>, </code><code>'wangwu'</code><code>]</code>
(2):
通過循環取值
<code>>>> r</code><code>=</code><code>[]</code>
<code>>>> n</code><code>=</code><code>3</code>
<code>>>> </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(n):</code>
<code> </code><code>r.append(l[i])</code>
<code>>>> r</code>
(3):
通過切片:
<code>>>> l[</code><code>0</code><code>:</code><code>3</code><code>]</code>
l[0:3] 表示從索引0開始,知道索引3為止,但不包括索引3.即索引0,1,2,正好是3個元素。
如果第一個索引是0,還可以省略:
<code>>>> l[:</code><code>3</code><code>]</code>
也可以從索引1開始,取出2個元素出來:
<code>>>> l[</code><code>1</code><code>:</code><code>3</code><code>]</code>
<code>[</code><code>'zhangsan'</code><code>, </code><code>'wangwu'</code><code>]</code>
也可以倒數切片:
<code>>>> l[</code><code>-</code><code>1</code><code>]</code>
<code>'xaiohua'</code>
<code>>>> l[</code><code>-</code><code>2</code><code>:]</code>
<code>[</code><code>'xiaoxin'</code><code>, </code><code>'xaiohua'</code><code>]</code>
建立一個0-99的數列:
<code>>>> L </code><code>=</code> <code>list</code><code>(</code><code>range</code><code>(</code><code>100</code><code>))</code>
<code>>>> L</code>
<code>[</code><code>0</code><code>, </code><code>1</code><code>, </code><code>2</code><code>, </code><code>3</code><code>, ..., </code><code>99</code><code>]</code>
取前十個元素:
<code>>>> L[:</code><code>10</code><code>]</code>
<code>[</code><code>0</code><code>, </code><code>1</code><code>, </code><code>2</code><code>, </code><code>3</code><code>, </code><code>4</code><code>, </code><code>5</code><code>, </code><code>6</code><code>, </code><code>7</code><code>, </code><code>8</code><code>, </code><code>9</code><code>]</code>
後十個元素:
<code>>>> L[</code><code>-</code><code>10</code><code>:]</code>
<code>[</code><code>90</code><code>, </code><code>91</code><code>, </code><code>92</code><code>, </code><code>93</code><code>, </code><code>94</code><code>, </code><code>95</code><code>, </code><code>96</code><code>, </code><code>97</code><code>, </code><code>98</code><code>, </code><code>99</code><code>]</code>
前11-20:
<code>>>> L[</code><code>11</code><code>:</code><code>20</code><code>]</code>
<code>[</code><code>11</code><code>, </code><code>12</code><code>, </code><code>13</code><code>, </code><code>14</code><code>, </code><code>15</code><code>, </code><code>16</code><code>, </code><code>17</code><code>, </code><code>18</code><code>, </code><code>19</code><code>]</code>
前10個數,,每兩個取一個:
<code>>>> L[</code><code>0</code><code>:</code><code>10</code><code>:</code><code>2</code><code>]</code>
<code>[</code><code>0</code><code>, </code><code>2</code><code>, </code><code>4</code><code>, </code><code>6</code><code>, </code><code>8</code><code>]</code>
所有數,每5個取一個:
<code>>>> L[</code><code>0</code><code>:</code><code>100</code><code>:</code><code>5</code><code>]</code>
<code>[</code><code>0</code><code>, </code><code>5</code><code>, </code><code>10</code><code>, </code><code>15</code><code>, </code><code>20</code><code>, </code><code>25</code><code>, </code><code>30</code><code>, </code><code>35</code><code>, </code><code>40</code><code>, </code><code>45</code><code>, </code><code>50</code><code>, </code><code>55</code><code>, </code><code>60</code><code>, </code><code>65</code><code>, </code><code>70</code><code>, </code><code>75</code><code>, </code><code>80</code><code>, </code><code>85</code><code>, </code><code>90</code><code>, </code><code>95</code><code>]</code>
<code>>>> L[::</code><code>5</code><code>]</code>
<code>>>> L[:]</code>
tuple也是一種list ,隻是tuple不可變。tuple也可以切片:
<code>>>> (</code><code>0</code><code>,</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>)[:</code><code>3</code><code>]</code>
<code>(</code><code>0</code><code>, </code><code>1</code><code>, </code><code>2</code><code>)</code>
字元串 ‘xxxxx’也可以看做一個list,每個元素就是一個字元。是以,字元串也可以切片
<code>>>> </code><code>'ABCDEFGHIKLMNOPQRST'</code><code>[:</code><code>3</code><code>]</code>
<code>'ABC'</code>
<code>>>> </code><code>'ABCDEFGHIKLMNOPQRST'</code><code>[::</code><code>2</code><code>]</code>
<code>'ACEGILNPRT'</code>
疊代
給定一個list或tuple,我們通過for循環來周遊這個list或tuple,這種周遊我們稱為 疊代(lteration)。
Python的<code>for</code>循環不僅可以用在list或tuple上,還可以作用在其他可疊代對象上。
list這種資料類型雖然有下标,但很多其他資料類型是沒有下标的,但是,隻要是可疊代對象,無論有無下标,都可以疊代,比如dict就可以疊代:
<code>>>> d </code><code>=</code> <code>{</code><code>'a'</code><code>:</code><code>1</code><code>,</code><code>'b'</code><code>:</code><code>2</code><code>,</code><code>'c'</code><code>:</code><code>3</code><code>}</code>
<code>>>> </code><code>for</code> <code>key </code><code>in</code> <code>d:</code>
<code> </code><code>print</code><code>(key)</code>
<code> </code>
<code>c</code>
<code>b</code>
<code>a</code>
因為dict的儲存不是按照list的方式順序排列,是以,疊代出的結果順序很可能不一樣。
預設情況下,dict 疊代的是 key 。如果要疊代 value,可以用
<code>for</code> <code>value </code><code>in</code> <code>d.values()</code>
如果要同時疊代key和value,可以用
<code>for</code> <code>k,v </code><code>in</code> <code>d.items()</code>
由于字元串也是可疊代對象。是以,也可以作用與 for 循環:
<code>>>> </code><code>for</code> <code>ch </code><code>in</code> <code>'ABC'</code><code>:</code>
<code> </code><code>print</code><code>(ch) </code>
<code>A</code>
<code>B</code>
<code>C</code>
如何判斷一個對象是可疊代對象呢?方法是通過collections子產品的Iterable類型判斷:
<code>>>> </code><code>from</code> <code>collections </code><code>import</code> <code>Iterable</code>
<code>>>> </code><code>isinstance</code><code>(</code><code>'abc'</code><code>,Iterable)</code>
<code>True</code>
<code>>>> </code><code>isinstance</code><code>([</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>],Iterable)</code>
<code>>>> </code><code>isinstance</code><code>(</code><code>123</code><code>,Iterable)</code>
<code>False</code>
如果要對list實作類似于 c 語言 那樣的下标循環怎麼辦?Python内置的 enumerate 函數 可以把一個list變成索引-元素對,這樣就可以在 for 循環中同時疊代索引和元素本身:
<code>>>> </code><code>for</code> <code>i,value </code><code>in</code> <code>enumerate</code><code>([</code><code>'A'</code><code>,</code><code>'B'</code><code>,</code><code>'C'</code><code>]):</code>
<code> </code><code>print</code><code>(i,value)</code>
<code>0</code> <code>A</code>
<code>1</code> <code>B</code>
<code>2</code> <code>C</code>
上面的<code>for</code>循環裡,同時引用了兩個變量,在Python裡是很常見的,比如下面的代碼:
<code>>>> </code><code>for</code> <code>x,y </code><code>in</code> <code>[(</code><code>1</code><code>,</code><code>1</code><code>),(</code><code>2</code><code>,</code><code>2</code><code>),(</code><code>3</code><code>,</code><code>3</code><code>)]:</code>
<code> </code><code>print</code><code>(x,y)</code>
<code> </code>
<code>1</code> <code>1</code>
<code>2</code> <code>2</code>
<code>3</code> <code>3</code>
<code></code>
本文轉自 nw01f 51CTO部落格,原文連結:http://blog.51cto.com/dearch/1761631,如需轉載請自行聯系原作者