python--11.6

来源:互联网 发布:淘宝如何最快提交订单 编辑:程序博客网 时间:2024/05/29 17:32

递归

def fact(n)    if n == 1:        return 1    return n * fact(n - 1)
  1. 步骤:确定递归公式、确定边界条件;递归算法解题简洁,但过深的调用会导致栈溢出。
  2. 计算机中,函数调用时通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,就会导致栈溢出(stock overflow)—解决方法:尾递归:在函数返回时,调用自身,且return语句中不能包含表达式
def fact(n):    return fact_iter(n, 1)def fact_iter(num, product):    if num == 1:        return product    return fact_iter(num - 1, num * product)    #尾递归中不能包含表达式
  1. 汉诺塔的实现
#汉诺塔的实现:每次如何就是把n-1个盘子,挪到指定的塔上,然后把最下面最大的盘子移到指定的柱子上。def move(n, a, b, c):    if n == 1:        print(a, '-->', c)        return    #如何用程序实现汉诺塔    n = n - 1    move(n, a, c, b)    print(a, '-->',c )    move(n, b, a, c)

高级特性–去繁就简

切片(slice)

L = list(range(101))L[20:-4]    #左在右不在L[:10]L[80:]L[:]    #复制一个list   L[:10:2]L[::3]
  1. 左在右不在:分片需要两个索引作为边界,第一个索引的元素包含在分片内,第二个不包含在分片内();
  2. 捷径:如果分片要包含序列开始、结尾的元素: numbers[:3] 、numbers[-3:]、numbers[:]空出开始、最后一个索引
  3. 步长:numbers[1:8:2]、numbers[6:3:-2]。步长为负数,则会从序列的尾部开始向左提取元素;步长为正数,从序列的头部开始向右提取元素;依然遵循左在右不在的原则

迭代(iteration)

  1. 判断是否可迭代—通过collections模块的iterable类型判断
from collections import Iterableisinstance('abc', Iterable)
    2.
#dict的iteration:d = {'a': 1, 'b': 2, 'c': 3}for key in d:   #only iteration key    print(key)for value in d.values():        #iteration value    print(value)for k, v in d.items():      #iteration key and value    print(k,v)  
#字符串也是可迭代对象for ch in 'ABC':    print(ch)
  1. 对list实现下标循环,使用内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身
for i, value in enumerate(['a', 'b', 'c']):    print(i, value)

列表生成式(List Comprehensions)-用来创建list

  1. for循环后面还可加上if判断,可以更精确地筛选内容
[x * x for x in range(1, 11) if x % 2 == 0]   [4, 16, 36, 64, 100]    #结果
  1. 使用两层循环,可以生成全排列
[m + n for m in 'ABC' for n in 'XYZ']['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']      #结果
  1. for循环可以同时使用两个或多个变量(dict.items() 会有key、value),也可以使用两个变量来生成list

  2. 把一个list中所有的字符串变成小写,通过lower()方法;非字符串类型没有该方法,可以用if筛选出来

L = ['Hello', 'World', 'IBM', 'Apple'][s.lower() for s in L]['hello', 'world', 'ibm', 'apple']

生成器(generator)–边循环,边计算

  1. 解决列表元素太多,占用太多空间问题—生成器中的列表元素可以按照某种算法推算出来,在循环的过程中不断推算后续的元素,用for循环迭generator(可迭代对象)
g = ( x * x for x in range(10))     #创建一个generatorfor n in g:    print(n)
  1. 创建generator方法:把列表生成式中的[]改成()把函数变成generator,含yield 关键字—-函数和generator的区别:函数是顺序执行,遇到return语句或者最后一行函数语句就返回,直接返回结果;而
  2. generator工作原理:在for循环的过程中不断计算出下一个元素,遇到yield语句就中断并返回,再次执行时从上次返回的yield语句处继续执行,遇到return语句或者执行到函数体最后一行语句,generator结束,for循环随之结束。普通函数调用直接返回结果,而generator函数调用实际返回一个generator对象。
    用for循环调用generator,拿不到generator的return语句的返回值,因为fib(6)中,只包含yield返回的语句。如果想要拿到,必须捕获StopIteration错误
def fib(max):    n, a, b = 0, 0, 1    while n < max:        yield b       #原来的函数:print b ---这样就定义了一个generator        a, b = b, a + b        n = n + 1    return 'done'
for n in fib(6):    print(n)
#通过捕捉错误读取return中的值g = fib(6)while True:    try:        x = next(g)        print('g:', x)    except StopIteration as e:        print('Generator return value:', e.value)        break

迭代器(Iterator)

  1. 可迭代对象(Iterable可作用于for循环的数据类型):一类是集合数据类型,如list、tuple、dict、set、str等;一类是generator,包括生成器和待yield的generator function。用isinstance(xxx, Iterable) 判断一个对象是否为Iterable对象。
  2. 迭代器(Iterator, 可被next() 函数调用,并不断返回下一个值的对象):generator都是Iterator对象,但list、tuple、dict虽然是Iterable,但不是Iterator ,可通过iter()函数来转换
  3. Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
原创粉丝点击