美文网首页
python+AI第六课

python+AI第六课

作者: M_小七 | 来源:发表于2019-11-11 21:23 被阅读0次
    函数作用域

    python中的作用域分4种情况

    • L:local,局部作用域,即函数中定义的变量
    • E:enclosing,嵌套作用域
    • G:global,全局作用域
    • B:built-in,内置作用域
      优先级:LEGB
      作用域局部>外层作用域>当前模块中的全局>python内置作用域
    # str = 90 #built-in作用域
    # print(str)
    
    g_counter = 33 #全局作用域
    # o_count = 77
    def outer():
        o_count = 0#嵌套作用域
        # g_counter = 334
        def inner():
            i_counter = 5 #局部作用域
            o_count = 90
            # print(i_counter)
            # print('out' + str(o_count))
            # print(o_count)
        print('before inner')
        print(o_count)
        inner()
        print('after inner')
        print(o_count)
    outer()
    

    python内可以执行,如下程序

    if 2 > 1:
        x = 3
    print(x)
    #3
    

    解释:在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的

    变量的修改
    注意:下面程序会报错

    x = 90
    def f2():
        print(x)
        x = 88
    f2()
    #程序会报错
    #local variable 'x' referenced before assignment
    

    这里调用f2函数的print(x)时,解释器会在局部作用域找,找到 x = 88,但x调用函数之前就已经声明了,所以报错

    global关键字
    当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下

    count = 10
    def outer():
        global count
        print(count)
        count = 100
        print(count)
    outer()
    #10
    #100
    

    nonlocal关键字
    global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了

    a =666
    def outer():
        out_count = 3
        def inner():
            nonlocal out_count
            out_count+=3
    
        inner()
        print(out_count)
    
    outer()
    #6
    
    递归函数

    定义:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
    递归函数的优点: 是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

    • 求n的阶乘
    def factorial (n):
        if n == 1:
            return 1
        return n * factorial(n - 1)
    
    result = factorial(6)
    print(result)
    #720
    
    • 斐波那契数列
      不是用递归的情况下
    def fibo(n):
    
        before=0
        after=1
        for i in range(n-1):
            ret=before+after
            before=after
            after=ret
            print(before, end='\t')
            # 1 1   2   3   5   8   13  21
        return ret
    
    print(fibo(8))
    #21
    

    使用递归

    def fibo(n):
    
        if n <= 1:
            return n
        return(fibo(n-1) + fibo(n-2))
    
    print(fibo(8))
    #21
    

    特点:
    ①.必须有一个明确的结束条件
    ②.每次进入更深一层递归时,问题规模相比上次递归都应有所减少
    ③.\color{blue}{递归效率不高},递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返 回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。)

    #避免重复计算,加速
    cache = {}
    def fibo(n):
        if n <= 1:
            return n
        if (n - 1) not in cache:
            cache[n - 1] = fibo(n - 1)
        if (n - 2) not in  cache:
            cache[n - 2] = fibo(n - 2)
        return cache[n - 1] + cache[n - 2]
    print(fibo(100))
    

    练习:水仙花数也被称为超完全数字不变数、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数,水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)。
    方法一

    import math
    for i in range(100, 1000):
        x = math.floor(i / 100)
        y = math.floor((i - x * 100) / 10)
        z = i - math.floor(i / 10) * 10
        if i == x ** 3 + y ** 3 + z ** 3:
            print(i, end=', ')
    

    方法二

    flowers = []
    def flower():
        for i in range(100,1000):
            baiwei = i // 100
            gewei = i % 10
            shiwei = (i // 10) % 10
            if gewei*gewei*gewei + shiwei*shiwei*shiwei + baiwei*baiwei*baiwei == i:
                flowers.append(i)
    flower()
    print(flowers)
    
    将函数存在模块中

    要让函数是可导入的,得先创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。
    我们将之前写的斐波那契数列和阶乘程序保存为.py文件,然后创建main.py,我们将在main内调用我们要使用的斐波那契数列和阶乘模块

    # 使用import 引入模块
    import jiecheng
    import fibo
    

    此时当我们只引入这两个模块后运行程序,会得到两个返回值


    main.jpg

    这是因为我们在斐波那契数列和阶乘程序内都执行了print(),当main导入这两个模块时,直接运行了print,我们可以将两个模块内print修改成

    if __name__ == '__main__':
        print()
    

    这样既可以在模块内运行,也可以倒入模块后调用后再执行

    • 导入特定的函数
    from 模块 import 特定函数
    模块.特定函数
    #多个函数时
    from 模块 import 特定函数1,特定函数2,特定函数...
    
    • 使用as给函数指定别名
      回顾之前学的给模块起别名,同样也可以给函数起别名
    import pandas as pd
    from pizza import make_pizza as mp
    
    • 导入模块中的所有函数
      使用星号(*)运算符可让Python导入模块中的所有函数
    from pizza import *
    

    这种方法不建议使用
    最佳的做法是,要么只导入你需要使用的函数,要么导入整个模块并使用句点表示法。这能让代码更清晰,更容易阅读和理解。

    练习:

    # -*- coding: utf-8 -*-
    # @Time    : 2019/11/11 13:02
    # @Author  : WenTing Men
    # @Email   : wentingmen@163.com
    # @File    : 练习.py
    # @Software: PyCharm
    '''
    1.有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前20项之和。
    '''
    
    fenzi = 2 # 分子
    fenmu = 1 # 分母
    sum_t = 0
    for i in range(1, 21):
        a = fenzi
        b = fenmu
        sum_t += (a / b)
        fenzi = a + b
        fenmu = a
    
    print(sum_t)
    

    答案:

    from functools import reduce
    def compute():
        result = 0
        lst = []
        fenzi = 2
        fenmu = 1
        lst.append(fenzi/fenmu)
        for i in range(19):
            fenmu, fenzi = fenzi, fenmu + fenzi
            # tmp = fenzi
            # fenzi = tmp + fenmu
            # fenmu = tmp
            lst.append(fenzi/fenmu)
        #for k in lst:
        #   result += k
        #
        result = reduce(lambda  x, y: x + y, lst )
        return  result
    
    print(compute())
    
    '''
    2.给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。
    '''
    num = input('输入一个不多于5位的正整数:')
    l = len(num)
    print(f'这个数是{l}位数')
    n = num[::-1]
    for i in n:
        print(i)
    
    '''
    3.有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
    '''
    
    n = int(input('请输入人数n:'))
    l1 = list(range(1, n+1))
    count = 0
    while len(l1) >= 1:
        l = l1[:]
        for i in range(0, len(l)):
            count = count + 1
            if count % 3 == 0:
                l1.remove(l[i])
    
    print(f'最后留下的是原来的第 {l[0]} ')
    
    
    
    '''
    4.题:编写一个程序,根据控制台输入的事务日志计算银行帐户的净金额。 事务日志格式如下所示:
    D 100
    W 200
    
    D表示存款,而W表示提款。
    假设为程序提供了以下输入:
    D 300
    D 300
    W 200
    D 100
    然后,输出应该是:
    500
    
    '''
    
    total = 0
    while True:
        d = input('请输入事务日志:')
        if not d:
            break
        event_log = d.split(" ")
        nub = int(event_log[1])
        if event_log[0] == "D":
            total += nub
        elif event_log[0] == "W":
            total -= nub
    
    print (total)
    
    '''
    5.机器人从原点(0,0)开始在平面中移动。 机器人可以通过给定的步骤向上,向下,向左和向右移动。 机器人运动的痕迹如下所示:
    UP 5
    DOWN 3
    LEFT 3
    RIGHT 2
    方向之后的数字是步骤。 请编写一个程序来计算一系列运动和原点之后距当前位置的距离。如果距离是浮点数,则只打印最接近的整数。
    例:如果给出以下元组作为程序的输入:
    UP 5
    DOWN 3
    LEFT 3
    RIGHT 2
    然后,程序的输出应该是:2
    
    '''
    
    import math
    while True:
        dirction = input("请输入方向:")
        if not dirction:
            break
        dirction = dirction.split(" ")
        if dirction[0] == "UP":
           u  = int(dirction[1])
        elif dirction[0] == "DOWN":
           d  = int(dirction[1])
        elif dirction[0] == "LEFT":
           l = int(dirction[1])
        elif dirction[0] == "RIGHT":
           r = int(dirction[1])
        #
    x = abs(u-d)
    y = abs(l-r)
    print(int(math.sqrt(x**2+y**2)))
    

    相关文章

      网友评论

          本文标题:python+AI第六课

          本文链接:https://www.haomeiwen.com/subject/qznzbctx.html