Python之生成器及内置函数篇4

时间:2021-09-09 19:16:18

一、可迭代对象

#1、什么是迭代?:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来
#2、可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代的对象
#3、迭代器:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象
#4、可迭代的对象:str,list,tuple,dict,set,file
  获取可迭代对象的方式:无须获取,python内置str,list,tuple,dict,set,file都是可迭代对象
  特点:
	内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象
#5、迭代器对象:文件对象本身就是迭代器对象
  1、获取迭代器对象的方式:
	执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象
  2、特点:
	内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
	内置有__iter__方法,执行该方法会拿到迭代器本身
		
#6. for循环原理分析:
  1、for 循环称之为迭代器循环,in后跟的必须是可迭代的对象
  2、for循环会执行in后对象的__iter__方法,拿到迭代器对象
  3、然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体
  4、周而复始,直到取值完毕,for循环会检测到异常自动结束循环

1)迭代器的例子

list1=[1,2,3]
iter_list1=list1.__iter__()
print(iter_list1.__next__())
print(iter_list1.__next__())
print(iter_list1.__next__())

2)文件也是可迭代对象

l=open('a.txt','r',encoding='utf-8')
iter_l=l.__iter__()
while True:
    try:
        print(iter_l.__next__())
    except StopIteration:
        break

二、生成器或迭代器的使用

生成器:
函数内包含有yield关键字,
再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象

总结yield:
1、为我们提供了一种自定义迭代器的方式,
   可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器
2、yield可以像return一样用于返回值,区别是return只能返回一次值,而yield可返回多次
   因为yield可以保存函数执行的状态

1)迭代器的使用

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
def chicken():
    print('=====>first')
    yield 1
    print('=====>sencond')
    yield 2
    print('=====>third')
    yield 3

obj=chicken()
print(obj)
# 生成器本质就是迭代器,也就是说生成器的玩法其实就是迭代器的玩法
print(obj.__iter__() is obj)
res1=obj.__next__()
print(res1)

res2=obj.__next__()
print(res2)

res3=next(obj)  # 简写
print(res3)
View Code

2)用生成器造成无穷多的数

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
def my_range():
    print('start........')
    n=0
    while True:
        yield n
        n+=1

obj=my_range()

print(obj.__next__())
print(obj.__next__())
print(obj.__next__())
print(obj.__next__())

for i in my_range():
    print(i)
View Code

3)创造一个自己的range

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
def my_range(start,stop,step=1):
    n=start
    while n < stop:
        yield n #yield 4
        n+=step #5


obj=my_range(3,7,2) #3,5,
print(obj.__next__())
print(obj.__next__())
View Code

 4) yield传值使用

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
def eat(name):
    print('%s ready to eat' %name)
    food_list=[]
    while True:
        food=yield food_list
        food_list.append(food)
        print('%s start to eat %s' %(name,food))

dog1=eat('user')
#1、必须初始化一次,让函数停在yield的位置
res0=dog1.__next__()
print(res0)

#2、接下来的事,就是喂狗
#send有两方面的功能
#1、给yield传值
#2、同__next__的功能
res1=dog1.send('泔水')
print(res1)
res2=dog1.send('骨头')
print(res2)
res3=dog1.send('shit')
print(res3)
View Code

 三、三元表达式

  把一个简单的普通的函数变成了一行代码,即三元表达式

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
def max2(x,y):
    if x > y:
        return x
    else:
        return y
res=max2(10,11)
print(res)
x=12
y=11

#三元表达式仅应用于:
#1、条件成立返回 一个值
#2、条件不成立返回 一个值
# res=x if x > y else y
# print(res)
def max2(x,y):
    return x 
View Code

 四、函数递归

1)设置递归限制次数

#函数递归:函数的递归调用,即在函数调用的过程中,又直接或间接地调用了函数本身
import sys
print(sys.getrecursionlimit())
sys.setrecursionlimit(10000)
print(sys.getrecursionlimit())

2)函数递归调用的例子

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
# 直接调用
def foo():
    print('from foo')
    foo()
foo()

# 间接调用
def bar():
    print('from bar')
    foo()
def foo():
    print('from foo')
    bar()
foo()
View Code

3)递归的概念

# 递归分为两个阶段
#1、回溯:
    # 注意:一定要在满足某种条件结束回溯,否则的无限递归
#2、递推

# 总结:
#1、递归一定要有一个明确地结束条件
#2、没进入下一次递归,问题的规模都应该减少
#3、在python中没有尾递归优化

4)递归小高潮,age(n-1)+2

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
def age(n):
    if n == 1:
        return 18
    return age(n-1)+2 #age(4)+2
# 分析
# age1 = 18
# age2 = 20
# age3 = 22
# age4 = 24
# age5 = 26
print(age(5))
View Code

5)递归特殊列表打印

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
items=[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,]]]]]]]]]]
def tell(l):
    for item in l:
        if type(item) is not list:
            print(item)
        else:
            tell(item)

tell(items)
View Code

五、匿名函数,lambda

# 有名函数
def foo(x,n):
    return x ** n
# ====》匿名函数
f=lambda x,n:x ** n
print(f(2,3))
print(f(2,4))

1)强调注意点

1 匿名的目的就是要没有名字,给匿名函数赋给一个名字是没有意义的。也就是使用一次
2 匿名函数的参数规则、作用域关系与有名函数是一样的
3 匿名函数的函数体通常应该是 一个表达式,该表达式必须要有一个返回值

2)匿名函数的应用

练习一,找出下面工资最高人,提示,max

salaries={
    'zhangsan':3000,
    'lisi':1000,
    'Mr.C':10000,
    'Tina':5000
}
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
salaries={
    'zhangsan':3000,
    'lisi':1000,
    'Mr.C':10000,
    'Tina':5000
}
print(max(salaries,key=lambda x:salaries[x]))
View Code

相应的求工资工资最低的那个人

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
print(min(salaries,key=lambda x:salaries[x]))
View Code

按照工资的高低顺序排列

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
salaries1=sorted(salaries,key=lambda x:salaries[x])  #默认是升序排
salaries2=sorted(salaries,key=lambda x:salaries[x],reverse=True) #降序
print(salaries1)
print(salaries2)
View Code

练习二,map,映射关系

 将列表变成成 [1,4,9,16,25]

nums=[1,2,3,4,5]
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
nums=[1,2,3,4,5]
res=map(lambda x:x**2,nums)
print(list(res))
View Code
将列表['zhangsan','lisi','Tina']中的所有元素加上"_SB"
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
names=['zhangsan','lisi','Tina']
res=map(lambda x:x+'_SB',names)
print(list(res))
View Code
之上升级需求['zhangsan','lisi','Tina','lufei'],除了'lufei'加"_NB"外,其他加"_SB"
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
names=['zhangsan','lisi','Tina','lufei']
res=map(lambda x:x+'_NB' if x == 'lufei' else x + '_SB',names)
print(list(res))
View Code

练习三,reduce,合并

求1+2+3+4......99+100的和

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
from functools import reduce
res1=reduce(lambda x,y:x+y,range(1,101),100)  # 出始值是100
res2=reduce(lambda x,y:x+y,range(1,101))      # 默认初始值是0
print(res1)
View Code

字符串拼接

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
l=['my','name','is','god']
res=reduce(lambda x,y:x+' '+y,l,'Oh,')
print(res)
View Code

练习四,过滤 filter

['zhangsan_sb','lisi_nb','Tina_sb','lufei_nb']过滤出后面是sb的人
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
names=['zhangsan_sb','lisi_sb','Tina_sb','lufei_nb']
# res1=filter(lambda x:True if x.endswith('sb') else False,names)  # 画蛇添足
res2=filter(lambda x:x.endswith('sb'),names)
print(list(res2))
View Code
过滤出工资大于4000的
salaries={
    'zhangsan':3000,
    'lisi':1000,
    'Mr.C':8000,
    'Tina':5000
}
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
res=filter(lambda k:salaries[k] >= 4000,salaries)
print(list(res))
View Code

六、生成式与生成器表达式

1)列表生成式

列表生成器基本操作
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
l=['egg%s' %i for i in range(10)]
print(l)

ll=('egg%s' %i for i in range(10))  # 节约内存
print(ll)
print(list(ll))

nums=[i**2 for i in range(10) if i > 3]
print(nums)
View Code
将names=['zhangsan','lisi_sb','wudalang','tangsan']中的名字全部变大写
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
names=['zhangsan','lisi_sb','wudalang','tangsan']
names=[name.upper() for name in names]
print(names)
View Code
将names=['zhangsan','lisi_sb','wudalang','tangsan']中以sb结尾的名字过滤掉,然后保存剩下的名字长度
Python之生成器及内置函数篇4Python之生成器及内置函数篇4
names=['zhangsan','lisi_sb','wudalang','tangsan']
l=[len(name) for name in names if not name.endswith('sb')]
print(l)
View Code

2)字典生成式

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
d={'user%i'%i:i for i in range(10) if i > 0}
print(d)

userinfo=[('egon','123'),('alex','456'),('wxx','679')]
dic={k:v for k,v in userinfo}
print(dic)
View Code

 3)生成器表达式

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
g=(i for i in range(10))
print(g)
print(next(g))
print(next(g))
print(next(g))

chicken=('egg%s' %i for i in range(3))
# print(chicken)
print(next(chicken))
print(next(chicken))
print(next(chicken))

with open('a.txt','r',encoding='utf-8') as f:
    nums=(len(line) for line in f)
    # print(nums)
# print(nums)
# print(next(nums))
print(max(nums))
View Code

强调:()和[] 的区别

七、import导入模块

1)如何导入模块

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
# 导入模块方式一
import spam
import spam as sm
# 使用方法
spam.read1()

# 导入模块方式二
# from spam import money,read1,read2,change
# from spam import *
# 使用方法
read1()
View Code

注意点,对于from spam import *,*指所有,也可对*进行控制

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
__all__=['money','read1']   # from spam import *,控制的就是*所导入的名字
View Code

2)定义模块的调试,避免到导入时执行调试的代码

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
# 当文件被当做脚本执行时__name__的值为"__main__"
# 当文件被导入时__name__的值为"模块名"
# print(__name__)
# main()可快速写成__name__ == '__main__'
if __name__ == '__main__': # 改行代码用于区分python文件的两种不同用途,应该写在文件末尾
    read1()
    read2()
    change()
View Code

3)模块之间嵌套导入

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
1、尽可能的避免嵌套导入模块
2、导入的模块,放入最后或执行函数导入
View Code

 4)不在同级目录下的导入

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
# 方法一,加路径
import sys
sys.path.append(r'D:\oldboyedu\manth-02\day-01\dir')
print(sys.path)  # sys.path是以当前执行文件为准的路径
import spam
# 方法二,在同级目录的子集
from dir import spam
from dir1.dir2 import spam # 在同级目录的孙集
View Code

5)在被导入的模块中再导入别人模块

Python之生成器及内置函数篇4Python之生成器及内置函数篇4
from . import m2   # 从当前路径寻找其他模块
from .. import m2  # 从上层路径寻找其他模块
View Code