递归函数 ------- 在函数内部可以调用自身本身的函数
定义一个计算阶乘的函数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,如需转载请自行联系原作者