Python函数精彩案例解析

来自CloudWiki
跳转至: 导航搜索
  • 示例5-4 编写函数,接收一个整数t为参数,打印杨辉三角前t行。
def yanghui(t):
    print([1])
    line = [1, 1]
    print(line)
    for i in range(2, t):
        r = []
        for j in range(0, len(line)-1):
            r.append(line[j]+line[j+1])
        line = [1]+r+[1]
        print(line)
  • 示例5-11 编写函数模拟猜数游戏。系统随机产生一个数,玩家最多可以猜5次,系统会根据玩家的猜测进行提示,玩家则可以根据系统的提示对下一次的猜测进行适当调整。
from random import randint

def guess(maxValue=100, maxTimes=5):
    #随机生成一个整数
    value = randint(1,maxValue)
    for i in range(maxTimes):
        prompt = 'Start to GUESS:' if i==0 else 'Guess again:'
        #使用异常处理结构,防止输入不是数字的情况
        try:
            x = int(input(prompt))
        except:
            print('Must input an integer between 1 and ', maxValue)
        else:
            #猜对了
            if x == value:
                print('Congratulations!')
                break
            elif x > value:
                print('Too big')
            else:
                print('Too little')
    else:
        #次数用完还没猜对,游戏结束,提示正确答案
        print('Game over. FAIL.')
        print('The value is ', value)
  • 示例5-12 编写函数,计算形式如a+aa+aaa+aaaa+...+aaa...aaa的表达式的值,其中a为小于10的自然数。
def demo(v, n):
    assert type(n)==int and 0<v<10, 'v must be integer between 1 and 9'
    result, t = 0, 0
    for i in range(n):
        t = t*10 + v
        result += t
    return result

print(demo(3, 4))
  • 示例5-13 编写函数模拟报数游戏。有n个人围成一圈,顺序编号,从第一个人开始从1到k(假设k=3)报数,报到k的人退出圈子,然后圈子缩小,从下一个人继续游戏,问最后留下的是原来的第几号。
from itertools import cycle

def demo(lst, k):
    #切片,以免影响原来的数据
    t_lst = lst[:]
    #游戏一直进行到只剩下最后一个人
    while len(t_lst)>1:
        #创建cycle对象
        c = cycle(t_lst)
        #从1到k报数
        for i in range(k):
            t = next(c)
        #一个人出局,圈子缩小
        index = t_lst.index(t)
        t_lst = t_lst[index+1:] + t_lst[:index]
    #游戏结束
    return t_lst[0]

lst = list(range(1,11))
print(demo(lst, 3))
  • 示例5-14 汉诺塔问题基于递归算法的实现。
  • 据说古代有一个梵塔,塔内有三个底座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,在移动盘子的过程中可以利用B座,但任何时刻3个座上的盘子都必须始终保持大盘在下、小盘在上的顺序。如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C即可。和尚想知道这项任务的详细移动步骤和顺序。这实际上是一个非常巨大的工程,是一个不可能完成的任务。根据数学知识我们可以知道,移动n个盘子需要2^n-1步,64个盘子需要18446744073709551615步。如果每步需要一秒钟的话,那么就需要584942417355.072年。
def hannoi(num, src, dst, temp=None):
    #声明用来记录移动次数的变量为全局变量
    global times
    #确认参数类型和范围
    assert type(num) == int, 'num must be integer'
    assert num > 0, 'num must > 0'
    #只剩最后或只有一个盘子需要移动,这也是函数递归调用的结束条件
    if num == 1:
        print('The {0} Times move:{1}==>{2}'.format(times, src, dst))
        times += 1
    else:
        #递归调用函数自身,
        #先把除最后一个盘子之外的所有盘子移动到临时柱子上
        hannuo(num-1, src, temp, dst)
        #把最后一个盘子直接移动到目标柱子上
        hannuo(1, src, dst)
        #把除最后一个盘子之外的其他盘子从临时柱子上移动到目标柱子上
        hannuo(num-1, temp, dst, src)
#用来记录移动次数的变量
times = 1
#A表示最初放置盘子的柱子,C是目标柱子,B是临时柱子
hannoi(3, 'A', 'C', 'B')