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

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

定义一个计算阶乘的函数fact(n):

1
2
3
4
fact(n) = n!
      = 1 2 3 x ... x (n-1) x n
     = (n-1)! x n
     = fact(n-1) x n

函数可以写为:

1
2
3
4
5
6
7
8
9
10
11
12
>>> def fact(n):   
       if n==1:    
          return 1
     return n*fact(n-1)
>>> fact(1)
1
>>>fact(5)
120
>>> fact(100)
93326215443944152681699238856266700490715968264381621
46859296389521759999322991560894146397615651828625369
7920827223758251185210916864000000000000000000000000


如果我们计算 fact(5),可以根据函数定义看到计算过程如下:

1
2
3
4
5
6
7
8
9
10
===> fact(5)
===5 * fact(4)
===5 * (4 * fact(3))
===5 * (4 * (3 * fact(2)))
===5 * (4 * (3 * (2 * fact(1))))
===5 * (4 * (3 * (2 * 1)))
===5 * (4 * (3 * 2))
===5 * (4 * 6)
===5 * 24
===120


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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> fact(1000)
Traceback (most recent call last):
  File "<pyshell#40>", line 1in <module>
      fact(1000
   File "<pyshell#33>", line 4in fact
       return n*fact(n-1)
   File "<pyshell#33>", line 4in fact
       return n*fact(n-1)  
   File "<pyshell#33>", line 4in fact
    return n*fact(n-1)
     。。。
     File "<pyshell#33>", line 4in fact
     return n*fact(n-1)
    File "<pyshell#33>", line 2in fact
        if n==1:
RuntimeError: maximum recursion depth exceeded in comparison

切片


取一个list或tuple的部分元素:

(1):

直接通过索引取值

1
2
3
>>> l=['xaioming','zhangsan','wangwu','xiaoxin','xaiohua']
>>> [l[0],l[1],l[2]]
['xaioming''zhangsan''wangwu']

(2):

通过循环取值

1
2
3
4
>>> r=[]
>>> n=3
>>> for in range(n):
     r.append(l[i])
1
2
>>> r
['xaioming''zhangsan''wangwu']

(3):

通过切片:

1
2
>>> l[0:3]
['xaioming''zhangsan''wangwu']


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

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

1
2
>>> l[:3]
['xaioming''zhangsan''wangwu']


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

1
2
>>> l[1:3]
['zhangsan''wangwu']


也可以倒数切片:

1
2
>>> l[-1]
'xaiohua'
1
2
>>> l[-2:]
['xiaoxin''xaiohua']


创建一个0-99的数列:

1
2
3
>>> L = list(range(100))
>>> L
[0123, ..., 99]



取前十个元素:

1
2
>>> L[:10]
[0123456789]


后十个元素:

1
2
>>> L[-10:]
[90919293949596979899]


前11-20:

1
2
>>> L[11:20]
[111213141516171819]


前10个数,,每两个取一个:

1
2
>>> L[0:10:2]
[02468]

所有数,每5个取一个:

1
2
3
4
>>> L[0:100:5]
[05101520253035404550556065707580859095]
>>> L[::5]
[05101520253035404550556065707580859095]
1
2
>>> L[:]
[0123, ..., 99]

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

1
2
>>> (0,1,2,3,4,5)[:3]
(012)



字符串 ‘xxxxx’也可以看做一个list,每个元素就是一个字符。因此,字符串也可以切片

1
2
3
4
>>> 'ABCDEFGHIKLMNOPQRST'[:3]
'ABC'
>>> 'ABCDEFGHIKLMNOPQRST'[::2]
'ACEGILNPRT'



迭代


给定一个list或tuple,我们通过for循环来遍历这个list或tuple,这种遍历我们称为 迭代(lteration)。



Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。

list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代:

1
2
3
4
5
6
7
>>> d = {'a':1,'b':2,'c':3}
>>> for key in d:
     print(key)
      
c
b
a


因为dict的储存不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。


默认情况下,dict 迭代的是 key 。如果要迭代 value,可以用 

1
for value in d.values()

如果要同时迭代key和value,可以用

1
for k,v in d.items()

由于字符串也是可迭代对象。因此,也可以作用与 for 循环:

1
2
3
4
5
6
7
>>> for ch in 'ABC':
     print(ch)    
 
      
A
B
C


如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:

1
2
3
4
5
6
7
>>> from collections import Iterable
>>> isinstance('abc',Iterable)
True
>>> isinstance([1,2,3],Iterable)
True
>>> isinstance(123,Iterable)
False

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

1
2
3
4
5
6
>>> for i,value in enumerate(['A','B','C']):
     print(i,value)
      
0 A
1 B
2 C


上面的for循环里,同时引用了两个变量,在Python里是很常见的,比如下面的代码:

1
2
3
4
5
6
>>> for x,y in [(1,1),(2,2),(3,3)]:
     print(x,y)
          
1 1
2 2
3 3





本文转自 nw01f 51CTO博客,原文链接:http://blog.51cto.com/dearch/1761631,如需转载请自行联系原作者
上一篇:WPF ComboBox 数据模板


下一篇:Asp系统的Python升级