美文网首页
day10-函数3

day10-函数3

作者: 2333_11f6 | 来源:发表于2018-11-16 19:20 被阅读0次

    10.1 变量的作用域

    • 1.变量的作用域

    变量在程序中能使用的范围

    • 2.全局变量

    a.声明在函数或类的外部的变量都是全局变量(python中)
    b.全局变量的作用域是从声明开始到整个py文件结束,任何位置都可以使用(作用域:从声明开始到文件结束)

    • 3.局部变量

    a.声明在函数或类的内部的变量都是局部变量(形参是局部变量)
    b.局部变量的作用域从声明开始到函数结束函数内任何位置都可使用(作用域:从声明开始到函数结束)

    # 全局变量
    a = 10       # 全局变量
    
    for x in range(10):    # 全局变量
        y = 20              # 全局变量
        print(x)
    
    print(x, y)             # 9 20 全局变量
    
    if True:
        b = 10              # 全局变量
    
    
    # 局部变量
    def func2(num1, num2):
        print(num1, num2)
        aa = 1                        # num1 num2 aa 都是局部变量
    
      1. global的使用

    语法:
    global 变量名
    变量名 = 值

    global - 关键字;只能在函数中使用,用来在函数中声明一个全局变量
    在函数中声明一个全局变量,如果函数已被调用则外部可使用该全局变量;可用于修改或创建全局变量(在函数中)。

    # 声明一个全局变量a1
    a1 = 100
    
    
    def test():
        # 声明一个局部变量a1
        # a1 = 200
        # print(a1)
        global a1     # 声明全局变量
        a1 = 200
        global b1
        b1 = 99        # 在函数中声明全局变量b1
        print(a1)
    
    
    # test()             # 200
    # print(a1)          # 100
    test()                #200
    print(a1)             #200
    
    • 5.nonlocal

    nonlocal只能在函数中使用
    当需要在局部1的局部中修改局部1变量的值,就使用nonlocal

    def func1():
        # 声明一个局部变量a2
        a2 = 'abc'
    
        #  python中函数可声明函数
        def func2(): # func2也只能在func1中使用
            a2 = 'python'
            print(a2)
            a3 = 111  # 此时a3作用域在func2中
        func2()         # python
        #print(a3)
        print(a2)       # abc
    
    
    func1()           #  python abc
    
    print('*'*88)
    def func1():
        # 声明一个局部变量a2
        a2 = 'abc'
    
        #  python中函数可声明函数
        def func2(): # func2也只能在func1中使用
            nonlocal a2     # 定义局部的局部变量
            a2 = 'python'
            print(a2)
            a3 = 111  # 此时a3作用域在func2中
        func2()         # python
        # print(a3)
        print(a2)       # python
    
    
    func1()           # python python
    
    
    functions = []
    for x in range(5):                  # 全局变量x = 4,固定了
        functions.append(lambda a: a*x)  # 循环时未调用函数则不执行
        # functions = [lambda a:x*a, lambda a:x*a, lambda a:x*a, lambda a:x*a]
    
    t1 = functions[0]      # x*a
    t2 = functions[2]      # x*a
    # 当调用时 全局变量x=4,则t1 = t2 = lambda a:4*a
    print(t1(2), t2(2))    # 8 8
    

    10.2 函数作为变量

    • python中,声明函数其实就是声明一个类型是function的变量。函数名就是变量名
    • 函数名作为变量除了用来调用函数获取返回值外,普通变量能做的,它都能做。
    # 声明int类型变量
    a = 10
    # 声明list类型变量
    b = [1, 2, 3]
    # 声明function类型的变量c
    c = lambda x:x*x
    print(type(c))         # <class 'function'>
    
    # 声明function类型的变量func1
    def func1(x):
        return x*x
    
    
    print(type(func1))     # <class 'function'>
    

    1.变量1给变量2赋值

    list1 = [1, 2, 3]
    list2 = list1         # 赋值
    print(list2[0])       # 1;使用
    
    # 声明一个函数变量func1
    def func1():
        print('我是函数1')
    
    
    f1 = func1         # 函数变量func1给f1变量赋值
    f1()               # 我是函数1;将f1当作函数使用
    

    2.将变量作为列表元素或字典的值

    list1 = ['我是列表1第一个元素', 2, 3]
    list2 = [list1, 4]
    print(list2[0][0])     # 我是列表1第一个元素
    
    # 声明一个函数变量func2
    
    
    def func2():
        print('我是函数2')
    
    
    # 将函数变量作为列表元素
    list3 = [func2, 100]
    print(list3[0]())          # 我是函数2 None
    

    3.将变量作为函数参数
    将函数1作为实参,传递给函数2,这里的函数2就是一个(实参)高阶函数。

    def test(x):
        print('test:', x)
        if not isinstance(x, int):
            x()
    
    
    a = 10
    test(a)         # 将a作为test的实参 10
    
    
    def test2():
        print('我是测试函数2')
    
    
    test(test2)            # test: <function test2 at 0x000001D02F328378>
                           # 我是测试函数2
    

    3.1 sort,max,min函数,都是高阶函数

    def sort(key=None, reverse=False):

    key - 类型为函数;
    确定排序的时候以什么值为标准来排序(默认情况下,以列表的元素的大小为标准来排序);
    需要传一个函数,函数需要1个参数1个返回值。
    这里的参数是列表的元素。
    reverse - 是否降序排序,需要传一个bool值

    #list2.sort(reverse=True)
    # list2.sort(reverse=True)
    
    
    """
    [1, 34, 20, 89, 8]  -> [1, 8, 20, 34, 89]
    index = 0   [1, 34, 20, 89, 8]
    index = 1   [1, 8, 34 ,89, 20]
    index = 2   [1, 8, 20, 89, 34]
    ...
    """
    
    def yt_sort(list1, key=None):
        # list1 = my_list2; key = get_age
        if key == None:
            # 直接对列表元素进行排序
            for index in range(len(list1)):
                for index2 in range(index+1, len(list1)):
                    current = list1[index]
                    behind = list1[index2]
                    if behind < current:
                        list1[index], list1[index2] = list1[index2], list1[index]
        else:
            for index in range(len(list1)):
                for index2 in range(index+1, len(list1)):
                    current = key(list1[index])
                    behind = key(list1[index2])
                    if behind < current:
                        list1[index], list1[index2] = list1[index2], list1[index]
    
    
    my_list = [1, 34, 20, 89, 8]
    yt_sort(my_list)
    # my_list.sort()
    print(my_list)
    
    my_list2 = [
        {'name': '张三', 'age': 18},
        {'name': '李四', 'age': 30},
        {'name': '王五', 'age': 10}
    ]
    # my_list2.sort() 
    # TypeError: '<' not supported between instances of 'dict' and 'dict'
    # yt_sort(my_list2) 
    # TypeError: '<' not supported between instances of 'dict' and 'dict'
    
    
    def get_age(x):
        return x['age']
    
    
    yt_sort(my_list2, get_age)
    print(my_list2)
    
    
    my_list2 = [
        {'name': '张三', 'age': 18, 'score': 90},
        {'name': '李四', 'age': 30, 'score': 80},
        {'name': '王五', 'age': 10, 'score': 89}
    ]
    
    # 取最大年龄对应的字典
    max_age = max(my_list2, key=lambda x: x['age'])
    print(max_age)
    
    # 取最大成绩对应的字典
    max_score = max(my_list2, key=lambda x: x['score'])
    print(max_score)
    
    
    # 练习:要求将按列表中元祖的第二个元素,获取最大值。
    my_list3 = [('z', 10), ('b', 30), ('c', 20)]
    print(max(my_list3, key=lambda item: item[1]))
    
    
    # max
    dict1 = {'a': 10, 'b': 5, 'c': 8}
    list3 = [('z', 10), ('b', 30), ('c', 20)]
    
    print(max(list3, key=lambda x: x[1]))       # ('b', 30)
    

    4.变量作为函数的返回值
    返回值是函数的函数,也叫高阶函数(返回值高阶函数)

    # int类型变量作为返回值
    def test2(n):
        s = 1
        for i in range(1, n+1):
            s *= i
        return s
    
    
    re = test2(5) + 10       # 130
    
    
    # 函数类型变量作为返回值
    
    
    def get_operation(char):     # 返回值高阶函数
        """
        根据不同的符号返回不同的功能(函数功能的描述)
        :param char: 运算符符号
        :return: 不同运算符对应的功能的函数
        """
        if char == '+':
            return my_sum
        elif char == '*':
            return mul
        elif char == '-':
            return diff
        else:
            print('暂时不支持这个运算符')
    
    
    def diff(*args, **kwargs):
        """
        求差
        :param args: 元组类型数据
        :param kwargs: 字典类型数据
        :return: 所有数据的累差
        """
        diff1 = 2*args[0]
        for item in args:
            diff1 -= item
        return diff1
        # diff1 = 2*kwargs[]
        # for key in kwargs:
        #     sum1 *= kwargs[key]
        # return sum(args)*sum1
    
    
    def mul(*args, **kwargs):
        """
        求积
        :param args: 元组类型数据
        :param kwargs: 字典类型数据
        :return: 所有数据的积
        """
        sum1 = 1
        for key in kwargs:
            sum1 *= kwargs[key]
        return sum(args)*sum1
    
    
    def my_sum(*args, **kwargs):
        """
        求和
        :param args: 元组类型数据
        :param kwargs: 字典类型数据
        :return: 所有数据的和
        """
        sum1 = 0
        for key in kwargs:
            sum1 += kwargs[key]
        return sum(args)+sum1
    
    
    print(get_operation('+')(1, 2, 3))     # 6
    re1 = get_operation('+')              # 函数
    print(re1(1, 2, 3))                  # 6 调用求和函数获取返回值
    re1 = get_operation('*')              # 函数
    print(re1(1, 2, 3))                  # 6 调用求积函数获取返回值
    
    re1 = get_operation('-')              # 函数
    print(re1(1, 2, 3))                  # -4 调用求累差函数获取返回值
    

    10.3 迭代器

    • 1.什么是迭代器(iter)
      迭代器是python中的容器类的数据类型,可以同时存储多个数据。取迭代器中的数据只能一个一个取,而且取出来的数据,在迭代器中就没有了。
    • 2.迭代器中数据来源

    a.将其他序列转换成迭代器
    b.使用生成式、生成器产生数据

    1.将数据转换成迭代器
    所有的序列都能转成迭代器

    # 将字符串转换成迭代器
    iter1 = iter('abcd')
    print(iter1)       # <str_iterator object at 0x000002237329B4E0>
    
    # 将列表转成迭代器
    iter2 = iter([1, 2, 3, 4])
    print(iter2)         # <list_iterator object at 0x000002237329B550>
    
    # 将字典转成迭代器
    iter3 = iter({'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5})
    print(iter3)        # <dict_keyiterator object at 0x000002237143B4A8>
    

    2.获取迭代器中的数据
    a.
    next(迭代器)或者迭代器._next_() - 取出迭代器中第一个元素(已经取出的元素再也回不到迭代器中了)。
    当迭代器是空时,使用next获取元素,会出现异常StopIteration

    print(next(iter1))             # a
    print(next(iter1))             # b
    print(next(iter1))             # c
    print(next(iter1))             # d
    #print(next(iter1))             # StopIteration
    
    print(iter2.__next__())        # 1
    print(iter2.__next__())        # 2
    # print(iter2.__next__())        # 3
    # print(iter2.__next__())        # 4
    

    b.
    通过for循环取出迭代器中每个元素

    for x in iter2:
        print('===', x)        # 3 4
    

    10.4 生成器

    • 1.什么是生成器
      生成器就是迭代器;迭代器不一定是生成器
      生成器就是带有yield关键字的函数的结果

    • 2.生成器怎么产生数据
      调用带有yield关键字的函数,拿到的结果就是一个生成器。生成器中元素就是yield关键字后面的值。
      只要函数中有yield关键字,调用函数就不会再执行函数体及获取返回值,而是创建一个生成器。
      当获取生成器元素时,才会执行函数的函数体,执行到yield语句为止,并且将yield后面的值作为结果返回;并且保存当前执行的位置获取下一个元素时,就从上次结束位置接着往下去执行函数,如果函数结束了,就出现StopIteration,直到函数结束或遇到yield为止。

    • 生成器对应的函数,执行完成遇到yield的次数决定了生成器能产生数据的个数。

    def func():
        i = 0
        while i < 10:
            yield i
            i += 1
    
    
    print(next(func()))     # 0
    for item in func():
        print(item)         # 0 1 2 3 4 5 6 7 8 9
    
    
    def func1():
        print('abc')
        yield 100
        return 10
    
    
    # 只要函数中有yield关键字,调用函数就不会再执行函数体及获取返回值,而是创建一个生成器。
    re = func1()
    print(func1())      # <generator object func1 at 0x00000150A4686938> 生成器
    
    # next(re)            # abc;执行re对应的函数的函数体,将yield关键字作为结果。
    # StopIteration: 10
    print('===', next(re))   # abc === 100 获取的是yield后面的值
    
    gener1 = func()         # 要先用一个变量接收,后面才会一个一个迭代
    print(next(gener1))     # 0
    print(next(gener1))     # 1
    print(next(gener1))     # 2
    
    
    def nums():
        for i in range(101):
            yield  i
    
    
    gener = nums()
    print(next(gener))     # 0
    print(next(gener))     # 1
    print(next(gener))     # 2
    
    
    # 生成无限个不重复学号
    def xue_hao():
        x = 1
        while 1:
            yield 'stu' + str(x)
            x += 1
    
    
    stu_xue = xue_hao()
    print(next(stu_xue))    # 1
    print(next(stu_xue))    # 2
    print(next(stu_xue))    # 3
    print(next(stu_xue))    # 4
    
    for _ in range(5):
        print(next(stu_xue)) # 5 6 7 8 9
    
    print(next(stu_xue))    # 10
    
    # 写一个生成器可以不断产生斐波那契数列:1,1,2,3,5,8,13,21。。。
    def f_s():
        x1 = x2 = 1
        yield x1
        yield x2
        while 1:
            t = x1 + x2
            yield t
            x1, x2 = x2, t
    
    
    def f_s1(n):
        pre_1 = 0
        pre_2 = 1
        for _ in range(n):
            yield pre_2
            pre_1, pre_2 = pre_2, pre_1 + pre_2
    
    
    nums = f_s()
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    
    nums = f_s1(20)
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    print(next(nums))
    

    相关文章

      网友评论

          本文标题:day10-函数3

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