【python】 迭代器、生成器、列表推导式
一、可迭代对象、迭代器
1、可以被for循环的数据类型(可迭代对象):
字符串(str)、列表(list)、字典(dict)、元祖(tuple)、range()
2、迭代器
2.1 将可迭代对象==>迭代器(__iter__())
st = 'abc' # 可迭代对象
st_iter = st.__iter__() # 迭代器
print(st_iter) # 返回 :<str_iterator object at 0x00000117E93A2F98>
2.2 将可迭代对象==>迭代器(iter(可迭代对象))
st = 'abc'
st_iter = iter(st)
print(st_iter)
# 返回 :<str_iterator object at 0x00000117E93A2F98>
2.3 迭代器取值(__next__())
# 1、调用函数内的方法去取值 st = 'abc'
st_iter = st.__iter__()
print(st_iter.__next__()) # 迭代器每次只取一次数据,取完一次后指针停留在当前位置,便于下次接着取值
print(st_iter.__next__())
print(st_iter.__next__()) # 返回:
a
b
c
2.4 迭代器取值(next(迭代器))
2、调用函数去取值 st = 'abc'
st_iter = st.__iter__()
print(next(st_iter))
print(next(st_iter))
print(next(st_iter))
# 返回:
a
b
c
3、可迭代对象与迭代器的区别:
1) 可迭代对象可以转换成迭代器,迭代器不能逆转;
2)可迭代对象的方法:__iter__()
迭代器的方法:__iter__()、__next__()
4、判断 可迭代对象(Iterable) 和 迭代器(Iterator) 的两种方法:
4.1 方法一:
判断对象是否有"__iter__"方法
如果有,返回True,是可迭代对象
st = 'abc'
print("__iter__" in dir(st)) # dir(o):显示所有的方法
返回:
True
4.2 方法二:
用isinstance()方法判断:
from collections import Iterable
from collections import Iterator
# 判断是否为可迭代对象,返回True
print(isinstance(st,Iterable))
# 判断是否为迭代器,返回True
print(isinstance(st.__iter__(),Iterator)) 控制台报错:
DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated,
and in 3.8 it will stop working # 注:有报错没关系,是因为版本的原因(3.7.3)
5、迭代器的意义:
节省内存
迭代器有惰性机制(每次只取一次数据)
不能反复,一直往下执行(如:有100条数据,第一次循环,执行5条数据,第二次循环,从第6条开始执行)
6、for循环的机制(for循环会自动生成迭代器)
for循环中内部含有__iter__方法会自动将可迭代对象转换成迭代器;
再调用__next__方法
有异常处理机制(打印next方法,会一直循环可迭代对象,当循环结束,打印next方法就会报错,所以报错的时候加上异常处理)
7、用迭代器实现for循环
list = [1,2,3,4]
# 1、先判断list是否是可迭代对象
if '__iter__' in dir(list):
# 2、转化成迭代器
list_iter = list.__iter__()
# 3、将迭代器里面的值依次取出并打印
while True:
try:
print(list_iter.__next__())
except StopIteration as e:
print("--- 打印完毕!---%s"%e)
break
else:
print("不是可迭代对象")
二、生成器
生成器的本质就是迭代器(所以自带__iter__() 和 __next__() 方法)
1、迭代器构建的三种方式:
- 可以用生成器函数
- 可以用各种推导式构建函数
- 可以通过数据转换
2、生成器函数(yield=>函数返回值)
def gener():
print(111)
yield 'aaa'
print(222)
yield 'bbb'
print(333)
g = gener()
print(g) # 打印生成器函数
print(g.__next__()) # 打印第一个返回值
print(g.__next__()) # 打印第二个返回值 返回:
<generator object gener at 0x000001EF1CDF0570>
111
aaa
222
bbb
3、return 和 yield 的区别
1) return : 返回值给调用者,并结束此函数
2)yield : 返回值给调用者,并将指针停留在当前位置
4、send
def gener():
print(111)
yield "aaa"
print(222)
ret = yield ("bbb")
print("----->",ret)
print(333)
yield "ccc"
print(444)
g = gener()
print(g)
print(g.__next__())
print(g.send(None))
print(g.send("BBB")) ## 给上一个 yield 赋值 返回:
<generator object gener at 0x000002BE42060570>
111
aaa
222
bbb
-----> BBB
333
ccc
5、send 与 __next__ 的区别
相同点:都是取迭代器里面的值
不同点: 1)send是给上一个yield赋值
2)send不能给第一个、最后一个yield赋值
三、列表推导式
1、列表推导式语法:
# 1.1 循环模式
l1 = [变量(或者加工后的变量) for 变量 in 可迭代数据类型] print(l1)
# 1.2 筛选模式
l1 = [变量(或者加工后的变量) for 变量 in 可迭代数据类型 if 条件]
print(l1)
2、生成器表达式语法(小括弧啊里面有类型列表推导式的都是生成器)
l2 = (变量(或者加工后的变量) for 变量 in 可迭代数据类型)
# 打印生成器
print(l2)
# 取值
for i in l2:
print(i)
3、实例
3.1 列表推导式
例一:30以内所有能被3整除的数
st = [i for i in range(31) if i % 3 ==0]
print(st)
例二:30以内所有能被3整除的数的平方
st = [i*i for i in range(31) if i % 3 ==0]
print(st)
例三:找到嵌套列表中名字含有两个“e”的所在名字
names = [['Tom','Billy','Jefferson','Andrew','Weseiy','Steven','Joe'],
['Alince','Jill','Ana','Wendy','Jennifer','sherry','Eva']]
ee_name = [ j for i in names for j in i if j.count('e') == 2 ]
print(ee_name)
3.2 字典推导式
例一:将一个字典的key和value对调
dict = {'a':1,'b':2}
new_dict = {dict[k]:k for k in dict}
print(new_dict)
例二:合并大小写对应的value值,将k统一成小写
dict = {'a':10,'b':34,'A':7,'z':3}
new_dict = {k.lower():dict.get(k.lower(),0)+dict.get(k.upper(),0)for k in dict.keys()}
print(new_dict)
3.3 集合推导式
例一:计算列表中每个值得平方,自带去重功能
set = {i**2 for i in [1,-1,2]}
print(set)
【python】 迭代器、生成器、列表推导式的更多相关文章
- python 迭代器,生成器与推导式
函数的动态传参 *args 动态接收所有位置参数 **kwargs 动态接收关键字参数 顺序: 位置参数, *args, 默认参数, **kwargs def func(*args, **kwargs ...
- Python之路----列表推导式和生成器的表达式
列表推导式 egg_list=['鸡蛋%s'%i for i in range(10)] print(egg_list) 列表推导式 推导过程 egg_list = [] for i in range ...
- python 三元表达式 列表推导式,生成器表达式。递归,匿名函数, 内置函数
三元表达式 三元表达式仅应用于: 1.条件成立返回一个值 2.条件不成立返回一个值 res = x if x>y else y print(res) name= input("姓名&g ...
- python基础17_列表推导式 vs 生成器表达式
[ ] 列表推导式,是用简单的语法来生成列表, ( ) 生成器表达式,是用简单的语法创建个生成器. 外观上仅括号不一样. 虽然写起来方便,但是读起来稍显费力,另外,不易调试. # 列表推导式 prin ...
- Python中的列表推导式
Python里面有个很棒的语法糖(syntactic sugar),它就是 list comprehension ,有人把它翻译成“列表推导式”,也有人翻译成“列表解析式”.名字听上去很难理解,但是看 ...
- python中的列表推导式——轻量级循环
列表推导式(list comprehension)是利用其他列表创建新列表(类似于数学术语中的集合推导式)的一种方法.它的工作方式类似于for循环,也很简单. 列表推导式书写形式: [表达式 for ...
- python基础之列表推导式
#列表推导式 ---> 返回的是列表 for语句 效率更高# 1*1 2*2 3*3 4*4 5*5 6*6 7*7 8*8 9*9# import time# to = time.clock( ...
- Python List comprehension列表推导式
http://blog.chinaunix.net/uid-28631822-id-3488324.html 具体内容需要进一步学习
- Python 速通爆肝、列表推导式、生成器、装饰器、生命游戏
列表推导式.赋值.切片(替换.插入).字符串处理与判断.enumerate().格式化字符串.读写文件.global 关键字.字符串startswith().类与对象.生成器.装饰器.Self.*ar ...
- python高级编程之列表推导式
1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...
随机推荐
- Python3学习之路~9.1 paramiko模块:实现ssh执行命令以及传输文件
我们一般使用linux的时候,都是在Windows上安装一个ssh客户端连接上去.那么从一台linux如何连接到另一条linux呢?使用ssh命令即可,因为每台linux机器自己都有一个ssh客户端. ...
- 【jdbc访问数据库获取执行sql转换json】
Talk is cheap.Show me your code. import java.sql.*; import java.util.HashMap; import java.util.Map; ...
- Golang 之协程详解
转自:https://www.cnblogs.com/liang1101/p/7285955.html 一.Golang 线程和协程的区别 备注:需要区分进程.线程(内核级线程).协程(用户级线程)三 ...
- [LeetCode] 45. Jump Game II_ Hard tag: Dynamic Programming
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- table添加正确的样式
以前在做表格的时候,会在表格<table>标签中添加一些属性,来改变表格的样式,经常用到的有这几个 width 表格的宽度border 表格边框的宽度cellpadding 单元边沿与其 ...
- Centos7下使用Ceph-deploy快速部署Ceph分布式存储-操作记录
之前已详细介绍了Ceph分布式存储基础知识,下面简单记录下Centos7使用Ceph-deploy快速部署Ceph环境: 1)基本环境 192.168.10.220 ceph-admin(ceph-d ...
- qt 画多边形(实现鼠标拖动节点)
---恢复内容开始--- 2018-01-06 这个小例子实现了移动鼠标,鼠标的坐标信息跟随鼠标移动,多边形的实现,鼠标点击可以拖动多边形点的位置,(其中有个问题?我在QMainWindow下,用mo ...
- setoolkit 制作钓鱼网页
由于是在虚拟机下实验,仅做示范 下载地址 git clone https://github.com/trustedsec/social-engineer-toolkit/ 终端输入setoolkit启 ...
- WinForm中 Asp.Net Signalr消息推送测试实例
p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)
C 模拟 题意:给的是一个矩形,然后√2 的速度走,如果走到边上就正常反射,走到角上,暂停反射,我们知道要不循环要不暂停,记录走到的点最短时间 /*************************** ...