python映射与组合 python映射函数_python映射与组合

python学习函数高级话题一:递归、lambda、映射map及其他相关,特殊列表处理等。

内容只是学习笔记,共同学习。

目标:学会分块拆分函数,分块打包,循环调用。

小函数用lambda表达式:更贴近数学表达,增加他人可阅读性和难度。

print("===========函数的高级话题一:递归、lambda、映射map================")
"""
函数涉及的概念:
1、耦合性:对于输入使用参数并且对于输出使用 return语句。一般来讲,你需要力求让函数独立于它外部的东西。参数和 return语句通常就是隔离对代码中少数醒目位
置的外部的依赖关系的最好办法。
耦合性:只有在真正必要的情况下使用全局变量。全局变量(也就是说,在整个模块中的变量名)通常是一种蹩脚的函数间进行通信的办法。它们引发了依赖关系和
计时的问题,会导致程序调试和修改的困难。
2、耦合性:不要改变可变类型的参数,除非调用者希望这样做。函数会改变传入的可变类型对象,但是就像全局变量一样,这会导致很多调用者和被调用者之间的耦合
性,这种耦合性会导致一个函数过于特殊和不友好。
3、聚合性:每一个函数都应该有一个单一的、统一的目标。在设计完美的情况下,每一个函数中都应该做一件事:这件事可以用一个简单说明句来总结。如果这个句子
很宽泛(例如,“这个函数实现了整个程序”),或者包含了很多的排比(例如,“这个函数让员工产生并提交了一个比萨订单”),你也许就应该想想是不是要将
它分解成多个更简单的函数了。否则,是无法重用在一个函数中把所有步骤都混合在一起的代码。
4、大小:每一个函数应该相对较小。从前面的目标延伸而来,这就比较自然,但是如果函数在显示器上需要翻几页才能看完,也许就到了应该把它分开的时候了。特别
是 Python代码是以简单明了而著称,一个过长或者有着深层嵌套的函数往往就成为设计缺陷的征兆。保持简单,保持简短。
5、耦合:避免直接改变在另一个模块文件中的变量。作为参考,记住在文件间改变变量会导致模块文件间的耦合性,就像全局变量产生了函数间的耦合一
样:模块难于理解和重用。在可能的时候使用读取函数,而不是直接进行赋值语句。
"""
print("===========1、递归函数================")
def mysum(L):
    if not L:
        return 0
    else:
        return L[0]+mysum(L[1:])
print(mysum([1,2,3,4,5]))

#进阶精简:
def mysum(L):
    return 0 if not L else L[0]+mysum(L[1:])

print("===========2、循环与递归函数================")
L=[1,2,3,4,5]
sum=0
while L:
    sum += L[0]
    L=L[1:]
print(sum)

L=[1,2,3,4,5]
sum=0
for i in L:
    sum += i
print('sum1:',sum)

print("===========3、处理任意结构================")
#Python isinstance()是一种实用程序函数,用于检查对象是否为特定类型。 我们可以使用它来执行类型检查并根据对象的类型执行操作。
l=[1,[2,[3,4],5],6,[7,8]]
def sumtree(l):
    sum=0
    for x in l:
        if not isinstance(x,list):  #判断x  isinstance(x,list)是否列表,格式见左边👈
            sum +=x
        else:
            sum += sumtree(x)    #相当于处理拆包
    return sum
print(sumtree(l))

print("===========4、函数对象:属性和注释================")
#间接函数调用
def echo(message):
    print(message)
echo('Direct call')
x=echo
x('Indirect call') #间接调用

def indirect(func,arg):
    func(arg)
indirect(echo,'Argument call!')  #间接调用

schedule = [(echo,'spam'),(echo,'Ham!')]
for (func,arg) in schedule:
    func(arg)


def make(label):
    def echo(message):
        print(label+':'+message)
    return echo
f = make('spam')
f('ham')
f('eggs')

print("===========5、函数内省================")
def func(a):
    b='spam'
    return b*a
print(func(8))

print(func.__name__)
print(dir(func))

print("===========6、函数注释================")
def func(a:'skam'=4,b:(1,10)=5,c:float=6):
    return a+b+c
print('1:',func(1,2,3))
print('2:',func())
print('3:',func(1,c=10))
print('4:',func(1,2))

print("===========7、匿名函数lambda================")
"""
由lambda表达式所返回的函数对象与由def创建并赋值后的函数对象工作起来是完全一样的,但是lambda有一些不同之处让其在扮演特定的角色时很有用。
· lambda是一个表达式,而不是一个语句。因为这一点, lambdaPython能够出现在语法不允许def出现的地方—例如,在一个列表常量中或者函数调用的参数中。此
外,作为一个表达式, lambda返回了一个值(一个新的函数),可以选择性地赋值给一个变量名。相反,def语句总是得在头部将一个新的函数赋值给一个变量名,
而不是将这个函数作为结果返回。
· lambda的主体是一个单个的表达式,而不是一个代码块。这个 lambda的主体简单得就好像放在def主体 return的语句中的代码一样。简单地将结果写成一个顺畅的表
达式,而不是明确的返回。因为它仅限于表达式, lambda通常要比def功能要小:你仅能够在 lambda主体中封装有限的逻辑进去,连if这样的语句都不能够使用。
这是有意设计的—它限制了程序的嵌套: lambda是一个为编写简单的函数而设计的,而def用来处理更大的任务。
"""
def func(x,y,z): return x+y+z
print(func(2,3,4))

f=lambda x,y,z:x+y+z  #跟以上内容一样
print(f(2,3,4))

x= (lambda a='fee',b='fie',c='foe':a+b+c)
print(x('wee'))  #替换掉第一个值

def knight():
    title = 'Sir'
    action =(lambda x:title+' '+x)
    return action
act = knight()
print(act('robin'))

"""
为什么使用 lambda
通常来说,1 ambda起到了一种函数速写的作用,允许在使用的代码内嵌入一个函数的定义。它们完全是可选的(你总是能够使用ef来替代它们),但是在你仅需要嵌入小段
可执行代码的情况下它们会带来一个更简洁的代码结构。例如,我们在稍后会看到回调处理器,它常常在一个注册调用(registration call)的参
数列表中编写成单行的lambda表达式,而不是使用在文件其他地方的一个def来定义,之后引用那个变量名(请看本章稍后的例子)。
 lambda通常用来编写跳转表(jump table,也就是行为的列表或字典,能够按照需要执行相应的动作。
"""
#与下面表达相同,但是很麻烦。不够简洁
def f1(x):return x**2
def f2(x):return x**3
def f3(x):return x**4
l2=[f1,f2,f3]
for i in l2:
    print('i2:',i(2))
print(l2[0](3))

l1 = [lambda x:x**2,
      lambda x:x**3,
      lambda x:x**4]
for i in l1:
    print('i:',i(2))
print(l1[0](3))

key = 'get'
s2={'already':(lambda :2+2),
 'get':(lambda :2*4),
 'one':(lambda :2**6)}[key]()
print('s2:',s2)

print("===========8、匿名函数lambda================")
#如何让语句简洁明了易懂
# if a:
#     b
# else:
#     c

# 上面内容可以 b if a else c 或者 (a and b) or c 来替代
print("===========8、嵌套函数lambda及作用域================")
#lambda是嵌套函数最大受益者
def action(x):
    return (lambda y:x+y)
act=action(99)
print(act)
print(act(2))

action = (lambda x:(lambda y:x+y))
act = action(99)
print(act(3))
print((lambda x:(lambda y:x+y))(99)(5))

print("===========9、在序列中映射函数map================")
counters = [1,2,3,4]
updated = []
for i in counters:
    updated.append(i+10)
print(updated)

def inc(x): return x+12
print(list(map(inc,counters)))

l3=list(map((lambda x:x+5),counters))
print('l3:',l3)

def mymap(func,seq):
    res=[]
    for x in seq:
        res.append(func(x))
    return res
l4= list(map(inc,[1,2,3]))
print('l4:',l4)
l5= mymap(inc,[1,2,3])
print('l5:',l5)

l6= pow(3,4)
print('l6:',l6)
l7 = list(map(pow,[1,2,3],[2,3,4]))
print('l7:',l7)

print("===========10、函数式编程工具filter和reduce================")
l8=list(range(-5,5))
l8=list(filter((lambda x:x>0),range(-5,5)))
print('l8:',l8) #可以用for i in range(-5,5):if i >0;append方式替代

#所有列表中所有数值之和和之差
from functools import reduce
l9 = reduce(lambda x,y:x+y,[1,2,3,4,5])
l10= reduce(lambda x,y:x*y,[1,2,3,4,5])
print('l9,l10:',l9,l10)

"""
回头思考一下:
1、lambda表达式和def语句区别与适用场景:
2、函数的递归、调用:
3、是否对以前自己写过代码块有帮助及以后代码精简美观有帮助?
"""

print("===========后续将继续学习函数迭代和解析================")