Python入门-匿名函数,递归函数,主函数
1.三目运算符
对简单的条件语句,可以用三元运算简写。三元运算只能写在一行代码里面 # 书写格式 result = 值1 if 条件 else 值2 # 如果条件成立,那么将 “值1” 赋值给result变量,否则,将“值2”赋值给result变量 result = 'the result if the if succeeds' if True else 'the result if the if fails and falls to the else part' print(result)
2.列表表达式
#需求:生成一个列表演示代码 #方式一:for循环方式==================================== newList1 = [] for i in range(1,7): newList1.append(i ** 2) print(newList1) #方式二:使用列表表达式================================= newList2 = [i ** 2 for i in range(1,7)] newList3 = [i ** 2 for i in range(1,10) if i % 2 == 1] print(newList2) print(newList3) #方法三:结合函数的使用================================= def out_put(letter): return [res for res in letter if "k" in res] print(out_put(["aa", "kk", "bb"]))
3.生成器
""" 通过列表生成式,可以直接创建一个列表,但是,受到内存限制,列表的容量是有限的,而且如果创建一个包含了100万个元素的列表,不仅会占用很大的内存空间,如果在使用的时候仅仅访问前几个元素,则大量的内存空间会被浪费掉 所以,如果列表中的元素可以通过某种算法计算,在循环中的过程中不断推算出后续的元素,这样就不必创建完整的列表,从而节省大量的内存空间,在Python,这种一边循环一边计算的机制,被称为生成器【generator】 定义生成器的方式: a.将列表生成式中的[]改为(),就是一个生成器 b.通过函数和关键字yield生成 """ #1,列表生成式和生成器之间的区别 list1 = [i ** 2 for i in range(5)] print(list1) print(type(list1)) gene1 = (i ** 2 for i in range(5)) print(gene1) print(type(gene1)) """ [0, 1, 4, 9, 16] <class 'list'> <generator object <genexpr> at 0x0000000004D0AF90> <class 'generator'> """ #2.获取生成器中的元素 #生成器也是一个可迭代对象,可以采用for循环或者next()获取其中的元素 #next():每调用一次,则会获取生成器中的一个元素 #方式一 print(next(gene1)) print(next(gene1)) print(next(gene1)) print(next(gene1)) print(next(gene1)) print("*" * 20) #注意:如果一个生成器中的元素通过next获取完毕,再次调用next,则会报错StopIteration【停止迭代】 #print(next(gene1)) #方式二 for num in gene1: print(num) #3.通过函数和yield关键字生成 #3.1普通函数 def test(n): for x in range(1,n + 1): print(x) t = test(10) print(t) #None print("*" * 20) #3.2 #yield:暂停 def test(n): for x in range(1,n + 1): print("hello",x) yield x print("x=%d" % (x)) t = test(10) print(t) # print(next(t)) # print(next(t)) # print(next(t)) # print(next(t)) # print(next(t)) # print(next(t)) #使用循环获取生成器中的所有的元素 while True: try: print(next(t)) except: break """ 总结: 工作原理:每次调用next的时候,函数会执行到yield停止,将yield后面的值返回,代码停止,下次再调用next 函数生成器会接着从yield后面的代码继续执行。。。。 生成器类似于返回值为一个列表的函数,这个函数可以接收参数,可以被调用,但是,不同于一般列表的地方在于: 一般的函数一次性返回一个非空的列表 ,生成器只能生成一个值,这样消耗的内存会减少 """ #一般函数 def func(n): list1 = [] for i in range(1,n + 1): list1.append(i) return list1 #生成器函数 def test(n): for x in range(1, n + 1): yield x
4.可迭代对象和迭代器
#1.可迭代对象 "”" 只能用for循环遍历的数据被称为可迭代对象【Iterable类】 可迭代对象的数据类型: a.集合数据类型:list,tuple,dict,set,str b.generator:包括()生成器和带yield关键字的函数 """ from collections import Iterable print(isinstance([],Iterable)) print(isinstance((),Iterable)) print(isinstance({},Iterable)) print(isinstance((x for x in range(4)),Iterable)) print(isinstance("abc",Iterable)) print(isinstance(10,Iterable)) print(isinstance(True,Iterable)) #2.迭代器 """ 不但可以使用for循环遍历,还可以被next函数调用的数据被称为迭代器【Iterator类】 迭代器的数据类型:生成器 """ from collections import Iterator print(isinstance([],Iterator)) print(isinstance((),Iterator)) print(isinstance({},Iterator)) print(isinstance("abc",Iterator)) print(isinstance(10,Iterator)) print(isinstance(True,Iterator)) print(isinstance((x for x in range(4)),Iterator)) #iter(),将一个不是迭代器的可迭代对象转换为迭代器 print(isinstance(iter([]),Iterator)) print(isinstance(iter(()),Iterator)) print(isinstance(iter({}),Iterator)) print(isinstance(iter("abc"),Iterator)) """ a.迭代器一定是可迭代对象,但是可迭代对象不一定是迭代器 b.通过iter()可以将一个不是迭代器的可迭代对象转换为迭代器【list,tuple,dict,set,str】 """
5.匿名函数
匿名函数表达式
lambda 参数迭代对象 : 表达式 #冒号之前是参数 : 冒号之后是表达式。 #参数可以一个或多个,也可以是默认值 res1 = lambda x: x**3 #一个参数 res2 = lambda x,y,z:x+y+z #多个参数 res3 = lambda x,y=3: x*y #允许参数存在默认值 print(res1(2)) #8 print(res2(2,3,4))#9 print(res3(2)) #6 """ # lambda返回的是函数对象(构建的是一个函数对象):<function <lambda> at 0x000002216672E040> # 所以匿名函数不需要return来返回值,需要定义一个变量去接收表达式本身结果。 """ #参数是可迭代对象即可:列表,字典,集合,元祖,字符串 #表达式:可以是lambda表达式, 列表表达式 lambda_func = lambda iterm_list: [num *num for num in iterm_list] print(lambda_func(list(range(5)))) #[0, 1, 4, 9, 16]
匿名函数和普通函数的对比
# 普通python函数 def func(a,b,c): return a+b+c # lambda匿名函数,表达式 f = lambda a,b,c:a+b+c print(f(1,2,3)) print(func(1, 2, 3)) """ 匿名函数:代码简单,逻辑简单的时候,匿名函数的定义更加简单方便 """
普通函数嵌套匿名函数
def func(num): return lambda x :x * num f = func(10) print(f) #返回的是函数对象 print(f(2)) """ <function func.<locals>.<lambda> at 0x000002642846C040> 20 """
匿名函数的联合使用
# lambda和map函数的联合使用-----求平方 res = map(lambda x: x*2, range(5)) print(list(res)) # [0, 2, 4, 6, 8] # lambda和filter函数的联合使用--求偶数 list1 = list(range(10)) res1 = filter(lambda x :x % 2==0, list1) print(list(res1)) #[0, 2, 4, 6, 8] # lambda和reduce函数的联合使用--列表求和 from functools import reduce list1 = list(range(10)) res3 = reduce(lambda x,y : x + y, list1) print(res3) #45
6.递归函数
""" 在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。 例如:累加或者阶乘,以指定数字为起点,以1为终点,从起点开始,一累加或者阶乘即可,到1时停止递归 """ # 100以内的数字求和,递归解法 def s(num): if num == 1: #定义1位终点 return 1 else: return num + s(num -1) #以指定数字为起点,不断调用自身 s(100) """ 解法过程:100+99+98....+3+2+1 """ 1.递归函数的优点:定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归简单清晰。 2.递归函数的缺点:使用递归函数需要注意防止栈溢出。 """ 在计算机中,函数调用是通过栈(stack)这种数据结构实现的, 每当进入一个函数调用,栈就会加一层栈帧【每当函数返回,栈就会减一层栈帧】, 而栈的大小不是无限的, 所以,递归调用的次数过多,会导致栈溢出。 可以试试s(1000),一定会报错。 """
7.主函数
当我们写了好几百行的代码,别人观看使用的时候,如何知道程序的起点呢?
我们自己写完好几个模块代码开始互相调用,但被调用的时候,有的代码不想别人可以使用怎么办呢?
以上问题都可以用主函数来解决,我们先看一下文件名字的秘密。
#模块1:test============ print(__name__) """ __main__ """ #模块2================= import test print(test.__name__) """ test test """ 当运行当前文件本身时:文件的--name--名字为--main-- 当文件被以模块被导入时:被导入的文件--name--名字就不是--main--,而是文件本身的名字,如test
定义主函数
#模块1:test================================================ def hello(): print("hello") if __name__ == "__main__": #定义主函数,下面为当前文件可执行代码 hello() print("主函数已经执行过了!") """ hello 主函数已经执行过了! """ #模块2===================================================== import test test.hello() # 调用test模块的hello方法 print("模块2正在调用:test模块") """ hello 模块2正在调用:test模块 """ 可见test模块中的主函数后面的代码,被导入后都没有执行!!
8.偏函数
#int函数可以把字符串转换为整型,默认为十进制,如果是二进制爱,八进制或者十六进制,每次都需要指明 print(int("110")) print(int("110",base=2)) print(int("110",2)) print(int("110",8)) print(int("110",16)) """ 110 6 6 72 272 """ #如果把此功能改为函数有下面几种方法 #方式一:定义一个默认参数的函数======================================== def int2(x,base=2): return int(x,base) #方式二:偏函数===================================================== import functools int2 = functools.partial(int,base=2) print(int2) print(int2("1101") #总结:根据一个已知的函数,通过控制该函数的参数生成一个新的函数,新的函数被称为偏函数 #当一个函数的参数过多的情况下,需要简化函数的调用,使用functools.partial创建一个新的函数,把原函数中的某些参数固定