• python函数的学习笔记


    这篇文章是我关于学习python函数的一些总结

    一、随着函数的引入,这里首先要说的就是全局变量和局部变量了。

    什么是全局变量、什么是局部变量:

    全局变量就是全局都能调用的变量,一般都在文件的开头,顶头写。

    局部变量就是在函数内定义的变量,其实这里不完全对,因为有一个关键字可以改变这一属性,就是global,如果局部变量的前面加入global声明的话,那么这个局部变量就变成了全局变量。

    下面来看一个例子:

    name = "全局变量"
    
    def test():
        name = "局部变量"
        print(name)
    
    def test1():
        global name
        name = "我现在变成了全局变量了"
        print(name)
    
    test()
    test1()

    ######输出结果######
    局部变量
    我现在变成了全局变量了
     a

    二、函数的作用域  

    函数的作用域,这里要理解,或者说要记住的就是:

    函数的作用域在定义函数的时候就已经固定,不会随着调用的位置改变而改变。

    下面来看个例子:

    name = "我是全局变量"
    def one_level():
        name = "我是第一层变量"
        def two_level():
            name = "我是第二层变量"
            def three_level():
                print(name)
            return three_level
        return two_level
    
    test = one_level()
    test()()
    

    上面的例子将会打印“我是第二层变量”,

    这个例子告诉我们,函数体内有变量取值的操作的时候,一定是从里到外的原则的。首先会在当前的函数体内找有没有这个函数的定义值,如果没有,就会在往上一层的函数找,就这样层层的找,直到找到为止。

     三、递归函数

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

    从字面意义上来理解就是消息的“传递”和“归来”。这样看来就是数据有一个去和回来的过程,

    举个旅游的例子:

    假如我在深圳,我要坐火车去北京旅游,中间由近及远的停靠站分别是:深圳-->南昌-->天津-->北京,列车整个过程有很多各站。

    那我买了往返票,终点就是我要中断这次旅程的条件。流程就是这样的:在深圳上车-->经过南昌-->经过天津-->最后到北京。回来就是反之。

    如果用代码实现的话,如下:

    train_station = ['shenzhen','nanchang','tianjing','beijing','heilongjiang','xinjiang']
    
    def journey(train_station):
        station = train_station.pop(0)
        if station == "beijing":
            print("到了北京了,我们玩了一天,坐火车回家。")
            return
        else:
            print("现在才到%s,还要继续坐火车。" % station)
        res = journey(train_station)
        print("现在返程,经过的停靠站是%s" % station)
        return res
    
    journey(train_station)
    

    输出结果是:

    现在才到shenzhen,还要继续坐火车。
    现在才到nanchang,还要继续坐火车。
    现在才到tianjing,还要继续坐火车。
    到了北京了,我们玩了一天,坐火车回家。
    现在返程,经过的停靠站是tianjing
    现在返程,经过的停靠站是nanchang
    现在返程,经过的停靠站是shenzhen
    

    递归函数的总结:

    1、递归函数必须要有一个结束条件,否则就死循环了。

    2、每次进入下一次递归,就越接近目标。

    3、递归层次过多会导致栈溢出,(就如坐火车旅游,去到越远的地方,你的时间越长,人就会越累。)

    尾递归优化:

    还是以上面的例子举例、假如你很牛逼,能让火车在经过的站点不停留直接就走,时间是不是就会少很多。

    体现在代码上面的话就是把赋值操作拿掉“res = journey(train_station)”。直接return journey(train_station)”。

    递归函数没有赋值操作了,在内存中就不需要增加栈帧信息了。

    四、匿名函数

    匿名函数就是没有名字的函数,语法结构如下:

    lambda 变量:运算

    #一般的函数运算
    def test(x):
        x = x +1
        return x
    print(test(5))
    
    #lambda函数
    a = lambda x:x+1
    print(a(5))
    
    以上两种、结果是一样的。
    

    一般来说,匿名函数不会想上面的例子一样使用,是配合其他函数使用的,例如map、reduce、filter

    下面结合map、reduce、filter、max、min函数来一起举例子:

    from functools import reduce   #注意,如果是python3.0以上版本的话需要导入一下
    
    #map结合lambda例子
    a_list = [1,4,7,12,22]
    
    a_new_list = list(map(lambda x:x*2,a_list))
    print(a_new_list)
    
    #reduce结合lambda例子1
    b_list = [4,10,4,5]
    
    b_new_list = reduce(lambda x,y:x+y,b_list)
    print(b_new_list)
    
    #reduce结合lambda例子2
    b_list = [4,10,4,5]
    
    b_new_list = reduce(lambda x,y:x+y,b_list,100)
    print(b_new_list)
    
    #filter结合lambda例子
    c_list = ['aaa_fc','bbb_fc','ccc_fc','ddd','eee']
    
    c_new_list = list(filter(lambda x:x.endswith('fc'),c_list))
    print(list)
    
    #max结合lambda例子
    m_dict2 = [{'name':'beijing','people':10000000},{'name':'tianjing','people':9000000},{'name':'nanchang','people':5000000}]


    print(max(m_dict2,key=lambda x:x['people']))
    #mix结合lambda例子
    print(min(m_dict2,key=lambda x:x['people']))
    #######输出结果########### 
    [2, 8, 14, 24, 44]
    23
    123
    ['aaa_fc', 'bbb_fc', 'ccc_fc']
    {'name': 'tianjing', 'people': 10000000}}
    {'name': 'tianjing', 'people': 5000000}


    总结:

    map函数:处理序列中的每一个元素,得到的结果是一个列表,该列表元素位置和原来一样

    reduce函数:处理一个序列,然后把序列进行合并操作

    filter函数:遍历序列中的每一个元素,判断每个元素得到的布尔值,如果为True就留下,返回的也是一个列表。

    max函数:遍历序列中的每一个元素,取最大值

    min函数:遍历序列中的每一个元素,取最小值

    五、高阶函数

    高阶函数的特征:

    1、传入的参数是函数名

    2、函数的返回值是函数名

    六、内置函数

    abs() :取绝对值

    all(): 判断可迭代对象的元素是否存在,为空、none,0。

    any(): 判断可迭代对象中是否包含空元素,包含则返回false,不包含返回True

    bin(): 转换为二进制的方法

    bool():转换为布尔值

    bytes(): 转换成字节

    callable(): 检查对象object是否可调用。

    chr(): 返回证书i对应的ascll字符。与ord()作用相反

    >>> chr(97)
    'a'

    compile(): 

    complex():

    divmod() : 返回的是a//b(除法取整)以及a对b的余数,返回结果类型为tuple元组

    enumerate() :遍历序列中的元素以及他们的下标

    m_dict2 = [{'name':'beijing','people':10000000},{'name':'tianjing','people':9000000},{'name':'nanchang','people':5000000}]
    print(list(enumerate(m_dict2)))
    打印:
    [(0, {'name': 'beijing', 'people': 10000000}), (1, {'name': 'tianjing', 'people': 9000000}), (2, {'name': 'nanchang', 'people': 5000000})]

    eval() :将字符串当成有效的表达式来求值并返回计算结果

    frozenset() :传入一个对象,生成一个新的不可变的集合

    hash():计算传入对象的哈希值

    hex() :将10进制转换成16进制

    id() :返回一个内存地址

    isinstance():用来判断传入对象的数据类型。

    issubclass()

    iter()

    locals():局部函数命名空间

    memoryview() :返回对象obj的内存查看对象。

    oct(): 十进制转换成八进制

    ord(): 用来返回对应字符的ascii码

    pow(): 下面的例子。就可以看出,如果传入两个参数就是计算次方,传入第三个参数的话就是取模

    例子:

    pow(4,2)

    >>16

    pow(4,2,2)

    >>0

    property():

    repr():将传入的对象变成字符串

    reversed() :取反,传入的可迭代对象,进过函数处理后得到一个反向的可迭代对象。

    l=[3,4,5,6]

    print(list(reversed(l)))

    >>[6,5,4,3]

    round() :返回浮点数的四舍五入值

    set() :

    slice():对传入的对象进行切片。

    sum():求和

    super()

    vars() :函数以字典形式返回参数中每个成员的当前值,如果vars函数没有带参数,那么它会返回包含当前局部命名空间中所有成员的当前值的一个字典。

    zip() :接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表

    m_dict1 = {'a':'1111','b':'22222','c':'112','d':'5555'}

    new_m_dict1 = list(zip(m_dict1.values(),m_dict1.keys()))
    print(new_m_dict1)
    >>[('1111', 'a'), ('22222', 'b'), ('112', 'c'), ('5555', 'd')]
  • 相关阅读:
    【LeetCode】048. Rotate Image
    【LeetCode】036. Valid Sudoku
    【LeetCode】060. Permutation Sequence
    【LeetCode】001. Two Sum
    【LeetCode】128. Longest Consecutive Sequence
    【LeetCode】081. Search in Rotated Sorted Array II
    【LeetCode】033. Search in Rotated Sorted Array
    顺时针打印矩阵
    矩形覆盖
    二维数组中的查找
  • 原文地址:https://www.cnblogs.com/xiaoqianghuihui/p/6682350.html
Copyright © 2020-2023  润新知