第六章 Python之迭代器与生成器
迭代器
迭代:迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果是下一次重复的初始值
l=['a','b','c']
count=0
while count < len(l):
print(l[count])
count+=1
迭代器:迭代器即迭代的工具,它的作用是无论对于序列类型(如str,list,tuple),还是对于非序列类型(如dict,set,文件)等,都能获取其中的值
可迭代对象:内置有obj.__iter__方法的对象
迭代器对象:既内置有obj.__iter__方法,又内置有obj.__next__方法的对象,可迭代对象执行obj.__iter__方法后得到的就是迭代器对象
#可迭代的对象,obj.__iter__
l=[1,2,3]
t=(1,2,3)
d={'name':'luoli','age':18,'sex':'female'}
s={'a','b','c'}
f=open('user.txt','r',encoding='utf-8')
l.__iter__()
t.__iter__()
d.__iter__()
s.__iter__()
f.__iter__()
#迭代器对象:既有obj.__iter__,又有obj.__next__方法
f.__next__()
可迭代对象不一定是迭代器对象,迭代器对象一定是可迭代的对象;可迭代对象调用obj.__iter__方法得到的是迭代器对象,迭代器对象调用obj.__iter__方法得到的是本身
d={'name':'luoli','age':18,'sex':'female'}
d_iter=d.__iter__()
print(d_iter.__next__())
print(d_iter.__next__())
print(d_iter.__next__())
print(d_iter.__next__()) #迭代器取值完毕抛出异常
for循环详解
#调用in后的对象的iter方法,使其成为一个迭代器:obj_iter=obi.__iter__--->调用next方法获取值:k=obj_iter.__next__()--->捕捉异常,结束迭代
d={'name':'luoli','age':18,'sex':'female'}
for k in d:
print(k) d={'name':'luoli','age':18,'sex':'female'}
d_iter=iter(d)
while True:
try:
print(next(d_iter))
except StopIteration:
break
迭代器优点:提供了一种统一的,不依赖于索引的取值方式,为for循环的实现提供了依据;更节省内存
缺点:只能往后并且一次性的取值;不能使用len()方法
生成器
只要函数内部包括yield关键字,那么函数名()得到的结果就是生成器,并且不会执行函数内部代码
生成器就是迭代器,yield提供了一种自定义迭代器的方法
yield与return的区别:yield可以返回多次值;函数暂停与继续的状态由yield保存
def func():
print('--1')
yield 1
print('--2')
yield 2
print('--3')
yield 3 #调用生成器函数将返回一个生成器
g=func()
#第一次调用生成器的next方法时,生成器才开始执行生成器函数(而不是构建生成器时),直到遇到yield时暂停执行(挂起),并且yield的参数将作为此次next方法的返回值
next(g)
#之后每次调用生成器的next方法,生成器将从上次暂停执行的位置恢复执行生成器函数,直到再次遇到yield时暂停,并且同样的,yield的参数将作为next方法的返回值
next(g)
next(g)
#如果当调用next方法时生成器函数结束(遇到空的return语句或是到达函数末尾),则这次next方法的调用将抛出StopIteration异常(即for循环终止的条件)
next(g)
yield表达式形式的用法
def eater(name):
print('%s ready to eat'%name)
food_list=[]
while True:
food=yield food_list #food=yield=banana
food_list.append(food)
print('%s start eat to eat %s'%(name,food))
print(food_list) e=eater('luoli')
#首先要初始化
next(e) #e.send(None)
#然后传值e.send()从暂停的位置将值传给yield,然后功能与next一样
e.send('banana')
e.send('peach')
练习
(1)自定义函数模拟range()
def my_range(start,stop,step=1):
while start < stop:
yield start
start+=step g=my_range(1,500,2)
print(next(g))
print(next(g))
print(next(g))
(2)模拟管道,实现功能:tail -f access.log | grep '404'
import time
def tail(filepath):
with open(filepath,'rb') as f:
f.seek(0,2)
while True:
line=f.readline()
if line:
yield line
else:
time.sleep(2)
print('run') def grep(lines,pattern):
for line in lines:
line=line.decode('utf-8')
if pattern in line:
yield line lines=grep(tail('access.log'),'')
for line in lines:
print (line)
三元表达式
def my_max(x,y):
if x>y:
return x
else:
return y x=20
y=30
res=x if x>y else y
列表推导式
l=['egg'+str(i) for i in range(1,11) if i>=6]
print(l)
生成器表达式
g=('egg'+str(i) for i in range(1,1000000000000))
print(g)
print(next(g))
print(next(g))
print(next(g))
# 练习
# 将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写
names=['egon','alex_sb','wupeiqi','yuanhao']
names=[name.upper() for name in names]
print(names) # 将names中以sb结尾的名字过滤掉,然后保存剩下的名字长度
names=[name for name in names if name.endswith('sb')]
print(names) # 求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数)
with open('a.txt','r',encoding='utf-8') as f:
# l=[]
# for line in f:
# #print(len(line))
# l.append(len(line))
res=max(len(line) for line in f)
print(res) # 求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?(需要使用sum函数) with open('a.txt','r',encoding='utf-8') as f:
res=sum(len(line) for line in f)
print(res)
练习
递归
递归调用:在调用一个函数的过程中,直接或者间接调用该函数本身,称之为递归调用
递归的两个阶段:1.递推 2.回溯
def func(n):
print('--->',n)
func(n+1) func(0) import sys
print(sys.getrecursionlimit()) #查看递归深度
sys.setrecursionlimit(2000) #修改递归最大深度
def age(n):
if n == 1:
return 18
return age(n-1) + 2 res=age(5)
print(res)
l=[1,[2,[3,[4,[5,[6,[7,]]]]]]] def func(l):
for item in l:
if type(item) is list:
func(item)
else:
print(item) func(l)
二分法
#实现类似l(num)的功能
l=[1,2,30,45,57,68,78,93,100] #从小到大排列的数字列表 def binary_search(l,num):
print(l)
if len(l) == 0:
print('not exist')
return
mid_index=len(l)//2
if num >l[mid_index]:
binary_search(l[mid_index+1:],num)
elif num < l[mid_index]:
binary_search(l[0:mid_index],num)
else:
print('find it') binary_search(l,688) #实现类似l(num,index)的功能
l=[1,2,10,20,30,55,67,87,92,102,293,304] def search(num,l,start=0,stop=len(l)-1):
if start <= stop:
mid=start+(stop-start)//2
print('start:[%s] stop:[%s] mid:[%s] mid_vla:[%s]'%(start,stop,mid,l[mid]))
if num > l[mid]:
start=mid+1
elif num <l[mid]:
stop=mid-1
else:
print('find it',mid)
return
search(num,l,start,stop)
else:
print('not exist')
return search(30,l)
匿名函数
lambda x,y:x+y
#应用
s='hello'
l=[1,2,3]
g=zip(s,l)
print(list(g)) salaries={
'lary':3000,
'jone':100000000,
'tom':10000,
'jerry':2000
} #zip/max/min/sorted/
g=zip(salaries.values(),salaries.keys())
print(max(g)) print(max(salaries,key=lambda k:salaries[k]))
print(min(salaries,key=lambda k:salaries[k]))
print(sorted(salaries,key=lambda k:salaries[k]))
print(sorted(salaries,key=lambda k:salaries[k],reverse=True)) #map
names=['lary','jone','tom','lily']
print(list(map(lambda name:"%s_01"%name,names))) #filter
names=['lary_01', 'jone_01', 'tom_01', 'lily']
g=filter(lambda x:x.endswith(''),names)
print(list(g)) from functools import reduce
print(reduce(lambda x,y:x+y,range(1,101),100))
应用
内置函数
查看内置函数:https://docs.python.org/3/library/functions.html?highlight=built
第六章 Python之迭代器与生成器的更多相关文章
- 第十六篇 Python之迭代器与生成器
一.迭代器 一. 递归和迭代 生活实例说明什么是递归和迭代 A想去腾达大厦,问B怎么走路,B 说我不知道,我给你问问C,C也不知道,C又去问D,D知道,把路告诉了C,C又告诉B,B最后告诉A, 这就是 ...
- python基础—迭代器、生成器
python基础-迭代器.生成器 1 迭代器定义 迭代的意思是重复做一些事很多次,就像在循环中做的那样. 只要该对象可以实现__iter__方法,就可以进行迭代. 迭代对象调用__iter__方法会返 ...
- python之迭代器与生成器
python之迭代器与生成器 可迭代 假如现在有一个列表,有一个int类型的12345.我们循环输出. list=[1,2,3,4,5] for i in list: print(i) for i i ...
- Python之迭代器和生成器
Python 迭代器和生成器 迭代器 Python中的迭代器为类序列对象(sequence-like objects)提供了一个类序列的接口,迭代器不仅可以对序列对象(string.list.tupl ...
- 【Python】迭代器、生成器、yield单线程异步并发实现详解
转自http://blog.itpub.net/29018063/viewspace-2079767 大家在学习python开发时可能经常对迭代器.生成器.yield关键字用法有所疑惑,在这篇文章将从 ...
- python的迭代器、生成器、装饰器
迭代器.生成器.装饰器 在这个实验里我们学习迭代器.生成器.装饰器有关知识. 知识点 迭代器 生成器 生成器表达式 闭包 装饰器 实验步骤 1. 迭代器 Python 迭代器(Iterators)对象 ...
- Python之迭代器,生成器
迭代器 1.什么是可迭代对象 字符串.列表.元组.字典.集合都可以被for循环,说明他们都是可迭代的. from collections import Iterable l = [1,2,3,4] t ...
- python之迭代器、生成器与面向过程编程
目录 一 迭代器 二 生成器 三 面向过程编程 一.迭代器 1.迭代器的概念理解 ''' 迭代器从字面上理解就是迭代的工具.而迭代是每次的开始都是基于上一次的结果,不是周而复始的,而是不断发展的. ' ...
- day13 python学习 迭代器,生成器
1.可迭代:当我们打印 print(dir([1,2])) 在出现的结果中可以看到包含 '__iter__', 这个方法,#次协议叫做可迭代协议 包含'__iter__'方法的函数就是可迭代函数 ...
随机推荐
- 洛谷P3958 奶酪 并查集
两个空洞可互达当且仅当两个空洞相切,即球心距离小于等于球的直径. 一一枚举两个可互达的空洞,并用并查集连起来即可. Code: #include<cstdio> #include<c ...
- 发现被坑了,从来没看到说java的Date一旦实例化时间就不会变了
java中使用Date对象获取系统当前时间,然而我就没看到哪篇教程告诉我说Date创建对象之后其中的时间是不会变的!!! 一开始我写了类似于下边这样的代码,希望每隔一段时间显示一次时间 Date d= ...
- Nginx Location指令配置及常用全局变量
./configure的含义 在实践安装nginx的时候,不知道./configure是什么意思,这里特地记录一下. 在linux中./代表当前目录,属于相对路径../代表上一级目录,属于相对路径/代 ...
- 记Spring搭建功能完整的个人博客「Oyster」全过程[其二] Idea中Maven+SpringBoot多模块项目开发的设计和各种坑(模块间依赖和打包问题)
大家好嘞,今天闲着没事干开写写博客,记录一下Maven+SpringBoot的多模块设计和遇到的坑. 多模块设计 简单说明一下截止目前的需求: 需要RESTful API:对文章.标签.分类和评论等的 ...
- ELK介绍及搭建 Elasticsearch 分布式集群
上:https://blog.51cto.com/zero01/2079879 下:https://blog.51cto.com/zero01/2082794
- SendKeys发送组合键
使用: using System.Windows.Forms;//添加命名空间引用 { SendKeys.SendWait("{DOWN}"); ppt.ppt_sendkey(& ...
- iOS相册实现与AssetsLibrary框架使用
概述 在iOS中如果想要获取手机相册里面的图片或者视频的话就要用到系统自带的AssetsLibrary框架,AssetsLibrary.framework中包含以下文件 #import <Ass ...
- POJ 3301
开始就是瞄着三分来做的,但看题目,感觉是旋转卡壳吧..可是,用了旋转卡壳还三分条毛啊.. 可以令正方形不旋转,而改为令点绕原点旋转,这样,很好的解决了问题,就可以比较X轴最大长度和Y轴最大长度来确定正 ...
- Mysql 奇怪的连接错误
今天,碰到了一个数据库连接问题: 不像之前在linux上mysql连接问题,那是权限设置.而这次问题的起源是: 我想要往mysql导入csv文件,可是因为文件比較大.有88M数据:使用navicatc ...
- Scrapy系列教程(6)------怎样避免被禁
避免被禁止(ban) 有些网站实现了特定的机制,以一定规则来避免被爬虫爬取. 与这些规则打交道并不easy,须要技巧,有时候也须要些特别的基础. 假设有疑问请考虑联系 商业支持 . 以下是些处理这些网 ...