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创建一个新的函数,把原函数中的某些参数固定

 

posted @ 2021-08-18 09:42  zwx901323  阅读(120)  评论(0)    收藏  举报