python基础2.0

递归函数:函数内部调用自身自己python

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

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

尾递归优化:设计模式

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个数,每两个取一个spa

2)迭代.net

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
相关文章
相关标签/搜索