天天看点

据廖雪峰python3教程----python学习第九天

递归函数 ------- 在函数内部可以调用自身本身的函数

定义一个计算阶乘的函数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>&gt;&gt;&gt; </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>&gt;&gt;&gt; fact(</code><code>1</code><code>)</code>

<code>1</code>

<code>&gt;&gt;&gt;fact(</code><code>5</code><code>)</code>

<code>120</code>

<code>&gt;&gt;&gt; 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>&gt; fact(</code><code>5</code><code>)</code>

<code>=</code><code>=</code><code>=</code><code>&gt; </code><code>5</code> <code>*</code> <code>fact(</code><code>4</code><code>)</code>

<code>=</code><code>=</code><code>=</code><code>&gt; </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>&gt; </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>&gt; </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>&gt; </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>&gt; </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>&gt; </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>&gt; </code><code>5</code> <code>*</code> <code>24</code>

<code>=</code><code>=</code><code>=</code><code>&gt; </code><code>120</code>

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试<code>fact(1000)</code>:

13

14

15

16

<code>&gt;&gt;&gt; fact(</code><code>1000</code><code>)</code>

<code>Traceback (most recent call last):</code>

<code>  </code><code>File</code> <code>"&lt;pyshell#40&gt;"</code><code>, line </code><code>1</code><code>, </code><code>in</code> <code>&lt;module&gt;</code>

<code>      </code><code>fact(</code><code>1000</code><code>) </code>

<code>   </code><code>File</code> <code>"&lt;pyshell#33&gt;"</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>"&lt;pyshell#33&gt;"</code><code>, line </code><code>4</code><code>, </code><code>in</code> <code>fact</code>

<code>    </code><code>File</code> <code>"&lt;pyshell#33&gt;"</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>&gt;&gt;&gt; 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>&gt;&gt;&gt; [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>&gt;&gt;&gt; r</code><code>=</code><code>[]</code>

<code>&gt;&gt;&gt; n</code><code>=</code><code>3</code>

<code>&gt;&gt;&gt; </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>&gt;&gt;&gt; r</code>

(3):

通过切片:

<code>&gt;&gt;&gt; l[</code><code>0</code><code>:</code><code>3</code><code>]</code>

l[0:3] 表示从索引0开始,知道索引3为止,但不包括索引3.即索引0,1,2,正好是3个元素。

如果第一个索引是0,还可以省略:

<code>&gt;&gt;&gt; l[:</code><code>3</code><code>]</code>

 也可以从索引1开始,取出2个元素出来:

<code>&gt;&gt;&gt; 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>&gt;&gt;&gt; l[</code><code>-</code><code>1</code><code>]</code>

<code>'xaiohua'</code>

<code>&gt;&gt;&gt; l[</code><code>-</code><code>2</code><code>:]</code>

<code>[</code><code>'xiaoxin'</code><code>, </code><code>'xaiohua'</code><code>]</code>

创建一个0-99的数列:

<code>&gt;&gt;&gt; L </code><code>=</code> <code>list</code><code>(</code><code>range</code><code>(</code><code>100</code><code>))</code>

<code>&gt;&gt;&gt; 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>&gt;&gt;&gt; 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>&gt;&gt;&gt; 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>&gt;&gt;&gt; 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>&gt;&gt;&gt; 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>&gt;&gt;&gt; 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>&gt;&gt;&gt; L[::</code><code>5</code><code>]</code>

<code>&gt;&gt;&gt; L[:]</code>

tuple也是一种list ,只是tuple不可变。tuple也可以切片:

<code>&gt;&gt;&gt; (</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>&gt;&gt;&gt; </code><code>'ABCDEFGHIKLMNOPQRST'</code><code>[:</code><code>3</code><code>]</code>

<code>'ABC'</code>

<code>&gt;&gt;&gt; </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>&gt;&gt;&gt; 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>&gt;&gt;&gt; </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>&gt;&gt;&gt; </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>&gt;&gt;&gt; </code><code>from</code> <code>collections </code><code>import</code> <code>Iterable</code>

<code>&gt;&gt;&gt; </code><code>isinstance</code><code>(</code><code>'abc'</code><code>,Iterable)</code>

<code>True</code>

<code>&gt;&gt;&gt; </code><code>isinstance</code><code>([</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>],Iterable)</code>

<code>&gt;&gt;&gt; </code><code>isinstance</code><code>(</code><code>123</code><code>,Iterable)</code>

<code>False</code>

如果要对list实现类似于 c 语言 那样的下标循环怎么办?Python内置的 enumerate 函数 可以把一个list变成索引-元素对,这样就可以在 for 循环中同时迭代索引和元素本身:

<code>&gt;&gt;&gt; </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>&gt;&gt;&gt; </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,如需转载请自行联系原作者