• python基础2.0


    递归函数:函数内部调用自身本身

    def fact(n):
        if n==1:
            return 1
        return n * fact(n - 1)
    

     使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。

    尾递归优化:

    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)
    

    可以看到,return fact_iter(num - 1, num * product)仅返回递归函数本身,num - 1num * product在函数调用前就会被计算,不影响函数调用。

    fact(5)对应的fact_iter(5, 1)的调用如下:

    ===> fact_iter(5, 1)
    ===> fact_iter(4, 5)
    ===> fact_iter(3, 20)
    ===> fact_iter(2, 60)
    ===> fact_iter(1, 120)
    ===> 120
    

     python的高级特性

    1)切片

    L[0:9:2]前10个数,每两个取一个

    2)迭代

    for ... in

    因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。

    字典的迭代

    默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()

    由于字符串也是可迭代对象,因此,也可以作用于for循环:

    >>> for ch in 'ABC':
    ...     print(ch)
    ...
    A
    B
    C
    

    所以,当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。

    3)列表生成式

    >>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
    >>> [k + '=' + v for k, v in d.items()]
    ['y=B', 'x=A', 'z=C']
    

     运用列表生成式,可以快速生成list,可以通过一个list推导出另一个list,而代码却十分简洁

    生成器:

    generator是非常强大的工具,在Python中,可以简单地把列表生成式改成generator,也可以通过函数实现复杂逻辑的generator。

    要理解generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。

    请注意区分普通函数和generator函数,普通函数调用直接返回结果:

    >>> r = abs(6)
    >>> r
    6
    

    generator函数的“调用”实际返回一个generator对象:

    >>> g = fib(6)
    >>> g
    <generator object fib at 0x1022ef948>
    

    定义生成器:generator function

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
        return 'done'
    

     生成式和生成器的区别

    >>> L = [x * x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g = (x * x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x1022ef630>
    

     迭代器:

    直接作用于for循环的对象统称为可迭代对象:Iterable

     生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

    凡是可作用于for循环的对象都是Iterable类型;

    凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

    集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

    高阶函数:

    map()函数接收两个参数,一个是函数,一个是Iterablemap将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

    >>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
    ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    

     reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算

    >>> from functools import reduce
    >>> def fn(x, y):
    ...     return x * 10 + y
    ...
    >>> def char2num(s):
    ...     digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    ...     return digits[s]
    ...
    >>> reduce(fn, map(char2num, '13579')
    

     用lambda函数进一步简化成:

    from functools import reduce
    
    DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    
    def char2num(s):
        return DIGITS[s]
    
    def str2int(s):
        return reduce(lambda x, y: x * 10 + y, map(char2num, s))
    

     filter函数:

    map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素

    一个序列中的空字符串删掉,可以这么写:

    def not_empty(s):
        return s and s.strip()
    
    list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))
    # 结果: ['A', 'B', 'C']
    

    filter()这个高阶函数,关键在于正确实现一个“筛选”函数。 注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回lis 

    def is_odd(n):
        return n % 2 == 1
     
    tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    newlist = list(tmplist)
    print(newlist)
    

     sorted()也是一个高阶函数。用sorted()排序的关键在于实现一个映射函数。

    sorted函数:sorted(iterable,key,reverse)

    其中iterable表示可以迭代的对象,  key是一个函数,用来选取参与比较的元素,reverse则是用来指定排序是倒序还是顺序,reverse=true则是倒序,reverse=false时则是顺序,默认时reverse=false

    以下返回值都是单一的key值排列或者value值排列

    d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
    >>>sorted(d.keys())
    ['Bob', 'Michael', 'Tracy']
    >>>sorted(d.values())
    [75, 85, 95]
    >>>sorted(d)
    ['Bob', 'Michael', 'Tracy']#默认就是根据key值排序
    >>>sorted(d,key=lambda x: d[x])#根据value值的大小对key排序
    ['Bob', 'Tracy', 'Michael']
    

     以下返回值是既包含key又包含value的列表,与上面的区别就是sorted的第一个参数不是d而是d.items(),d.items会把d变成一个可迭代对象.

    d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
    >>>d.items()
    dict_items([('Michael', 95), ('Bob', 75), ('Tracy', 85)])
    >>>sorted(d.items(),key=lambda x : x[1])
    [('Bob', 75), ('Tracy', 85), ('Michael', 95)]
    >>>d = {'data1':3,'da':1,'dat':2,'data22':4,'aa':3,'ff':0}
    >>>sorted(d.items(),key=lambda x :(x[1],x[0]))#对dict先根据value排序,value相等的根据key排序
    [('ff', 0), ('da', 1), ('dat', 2), ('aa', 3), ('data1', 3), ('data22', 4)]
    sorted(d.items())#根据key值对整个dict排序
    [('aa', 3), ('da', 1), ('dat', 2), ('data1', 3), ('data22', 4), ('ff', 0)]
    

    返回函数

    高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

    def lazy_sum(*args):
        def sum():
            ax = 0
            for n in args:
                ax = ax + n
            return ax
        return sum
    

    我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。 

    闭包:

    def 外层函数(参数):
        def 内层函数():
            print("内层函数执行", 参数)
    
        return 内层函数
    
    
    内层函数的引用 = 外层函数("传入参数")
    内层函数的引用()
    

     匿名函数:

    lambda x: x * x

    装饰器:https://blog.csdn.net/weixin_39541558/article/details/79972104

    在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。

    decorator可以增强函数的功能,定义起来虽然有点复杂,但使用起来非常灵活和方便。

    偏函数:

    functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

    functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2

    >>> import functools
    >>> int2 = functools.partial(int, base=2)
    >>> int2('1000000')
    64
    >>> int2('1010101')
    85
    
  • 相关阅读:
    mysql 压缩备份 压缩还原 命令
    $' ': command not found
    CentOS7查看和关闭防火墙
    Linux系统运维故障排查
    使用netstat、lsof查看端口占用情况
    一道关于二叉树遍历的题目
    curl常用传参方式
    vm centos7中用NAT模式配置上网
    laravel使用过程中一些总结
    MySQL Replication
  • 原文地址:https://www.cnblogs.com/icat-510/p/10811533.html
Copyright © 2020-2023  润新知