Python自学笔记D3

第三天,递归函数及高级特性

一、递归函数

一个函数在内部调用自身本身,这个函数就是递归函数。

def jiecheng(n):
    if n == 1:
        return 1
    return n * jiecheng(n - 1)

使用递归函数需要注意防止栈溢出。

在计算机中,函数调用是通过栈这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。
由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

以下为使用了尾递归(避免在return中进行运算)的阶乘

def digui(i):#阶乘
    return digui2(i,1)
def digui2(num,sum):
    if num == 1:
        return sum
    return digui2(num-1,num*sum)
print(digui(5))

汉诺塔解法https://baike.baidu.com/item/%E6%B1%89%E8%AF%BA%E5%A1%94/3468295#5_1

高级特性

一、切片

取L[‘a’,‘b’,‘c’,‘d’,‘e’]中前三个元素,循环较为麻烦,切片非常方便,即L[0:3]或者L[:3](0-3不包括3,不影响L本体)

List、tuple、字符串都能切,
‘ABCDEFG’[::2]==>‘ACEG’

作业:去除字符串首尾空格

s='       '
def crim(s):
    i = 0
    j = len(s) -1   
    while i<len(s)-1 and s[i] == ' ':
        i=i+1
    while j>0 and s[j] == ' ' :
        j=j-1
    return s[i:j+1],print(s[i:j+1])
crim(s)

二、迭代

扫描二维码关注公众号,回复: 11332601 查看本文章

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代。
调用iterable可以检测是否可以迭代。

from collections.abc import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False

Python的for循环抽象程度要高于C的for循环,因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上

d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
    print(key)
a
b
c

如果要迭代value,可以用for value in d.values()
如果要同时迭代key和value,可以用for k, v in d.items()。

Python内置的enumerate函数可以把一个list变成索引-元素对,变换后可以使用下标来对list进行读取。
for i, value in enumerate([‘A’, ‘B’, ‘C’]):

作业:找寻最大最小值

def findMinAndMax(L):
    if len(L) == 0:
        return(None,None)
    else:
        max=L[0]
        min=L[0]
        for x in L:
            if x > max:
                max = x
        for y in L:
            if y < min:
                min = y
        return (min, max)

三、列表生成式

Python内置的非常简单却强大的可以用来创建list的生成式

[x * x for x in range(1, 11)]#生成[1,4,...]
[x * x for x in range(1, 11) if x % 2 == 0]#上面的偶数
import os # 导入os模块,模块的概念后面讲到
>>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目录
for k, v in d.items():#也可使用.item代替dic中的key和value
    print(k, '=', v)

使用两个变量生成list、和变小写:

d = {'x': 'A', 'y': 'B', 'z': 'C' }
[k + '=' + v for k,v in d.items()]
 L = ['Hello', 'World', 'IBM', 'Apple']
>>> [s.lower() for s in L]#变小写

跟在for后面的if是筛选条件,不能加else!
for之前的if是表达式,必须加else!

作业:判断是否是字符串后变小写

L2 = [s.lower() for s in L1 if(isinstance(s,str))]

四、生成器generator

将元素通过算法计算,并且一边循环一边计算的机制,称为生成器。

将列表生成式中的[]换成()就可以了!
打印元素需要使用for n in g : print(n)来进行打印。

第二种方法:有yield(一般的print)就是generator

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

generator和函数的执行流程不一样:函数是顺序执行,遇到return语句或者最后一行函数语句就返回;而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中

g = fib(6)#接上一步代码,不过最简单还是使用for输出
while True:
     try:
        x = next(g)
        print('g:', x)
     except StopIteration as e:
        print('Generator return value:', e.value)
        break

作业:输出杨辉三角:

def triangles():#第一种方法
    currLine = [1]
    while True:
        yield currLine
        newLine = [1]
        for i in range(len(currLine)-1):
            newLine.append(currLine[i] + currLine[i+1])
        newLine.append(1)
        currLine = newLine
 def triangles()#最优解
    list = [1]
    while True:
        yield list
        list = [1] + [list[x] + list[x+1] for x in range(len(list)-1)] + [1]

n = 0#检测是否正确
results = []
for t in triangles():
    results.append(t)
    n = n + 1
    if n == 11:
        break

for t in results:
    print(t)

五、迭代器

literable

一类是集合数据类型,如list、tuple、dict、set、str等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对Iterable。

而可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

from collections.abc import Iterable
isinstance([], Iterable)
True             #判断是否是可迭代对
from collections.abc import Iterator
isinstance((x for x in range(10)), Iterator)
True             #判断是否是迭代器

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator(使用type可以查看类型)

把list、dict、str等Iterable变成Iterator可以使用iter()函数

因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。

可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

for x in [1, 2, 3, 4, 5]:
    pass
#等价于
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
    try:
        # 获得下一个值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出循环
        break

猜你喜欢

转载自blog.csdn.net/qq_43517875/article/details/106784239
D3
今日推荐