一、迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象
迭代器对象从集合的第一个元素开始访问,知道所有的元素访问完结束。迭代器只能往前不会后退
迭代器有两个基本的方法:__item__()和__next__()
1. dir ()
用来查看数据类型的数据能够执行那些方法,而得到所有的带'__iter__'可以使用for循环,就是可迭代对象
print(dir(str))
E:\Anaconda\python.exe F:/老男孩python/作业训练/8.10/
Train.py
['__add__',
'__class__',
'__contains__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__getnewargs__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mod__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__rmod__',
'__rmul__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'capitalize',
'casefold',
'center',
'count',
'encode',
'endswith',
'expandtabs',
'find',
'format',
'format_map',
'index',
'isalnum',
'isalpha',
'isdecimal',
'isdigit',
'isidentifier',
'islower',
'isnumeric',
'isprintable',
'isspace',
'istitle',
'isupper',
'join',
'ljust',
'lower',
'lstrip',
'maketrans',
'partition',
'replace',
'rfind',
'rindex',
'rjust',
'rpartition',
'rsplit',
'rstrip',
'split',
'splitlines',
'startswith',
'strip',
'swapcase',
'title',
'translate',
'upper',
'zfill']
Process finished with exit code 0
2. __next__()
可迭代对象可以使用__iter__()来获取到迭代器,而在迭代器中有__next__()
s =
"这是一个可迭代对象"
it = s.
__iter__()
# 获取迭代器
print(dir(it))
# 迭代器里有__iter__ 还有__next__
E:\Anaconda\python.exe F:/作业训练/8.10/
Train.py
['__class__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__length_hint__',
'__lt__',
'__ne__',
'__new__',
'__next__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__setstate__',
'__sizeof__',
'__str__',
'__subclasshook__']
Process finished with exit code 0
3.特点:
- 只能向前
只能向下一步进行,不能将之前的结果重新获取
- 几乎不占用内存
只有需要的时候,他才给出运行
- for循环
# 迭代器模拟for 循环
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9
, 0]
for el
in lst:
# 底层用的就是迭代器
print(el)
it = lst.
__iter__()
# 获取迭代器
while 1
:
try:
# 尝试执行
el = it.
__next__()
# 获取下一个元素
print(el)
except StopIteration:
# 处理错误
break # 当执行到最后的时候跳出
- 惰性机制
每执行一次'__next()',才给出一个结果,不执行就不给
s =
"这是一个可迭代对象"
it = s.
__iter__()
# 获取迭代器
print(it.
__next__())
# "这"
print(it.
__next__())
# "是"
print(it.
__next__())
# "一"
print(it.
__next__())
# "个"
print(it.
__next__())
# "可"
print(it.
__next__())
# "迭"
print(it.
__next__())
# "代"
print(it.
__next__())
# "对"
print(it.
__next__())
# "像"
print(it.
__next__())
# 超出了迭代范围会报错 "print(it.__next__()) StopIteration"
4. 如何判断
from collections
import Iterable
# 可迭代对象
from collections
import Iterator
# 迭代器
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9
, 0]
it = lst.
__iter__()
# 获取迭代器
print(isinstance(lst, Iterable))
# True 为可迭代对象
print(isinstance(lst, Iterator))
# False 不为迭代器
print(isinstance(it, Iterable))
# True
print(isinstance(it, Iterable))
# True
# 偏方
print(
"__iter__" in dir(it))
# T
print(
"__n__" in dir(it))
# F
5. list()
list(参数)把参数进行循环迭代
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9
, 0]
it = lst.
__iter__()
s =
list(it)
print(s)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
此处的list如果问set 则输出的就是一个集合,其他如tuple等相同
我们可以把要迭代的内容当成子弹,然后呢获取到迭代器"__iter__()",就把子弹都装在弹夹中,然后发射就是“__next__”把每一个子弹(元素)打出来,也就是说:for 循环的时候,一开始的时候是"__"来
获取迭代器,后面每次获取元素都是通过"__next__()"来完成的,当程序遇到Stoplteration将结束循环.
二、生成器
生成器的本质就是迭代器
在Python中,使用了yield的函数被称为生成器(generatoor)
生成器一般由生成器函数或者生成器表达式来创建
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单理解生成器就是一个迭代器
在调用生成器允许的过程中,每次遇到 yield 时函数会暂时保存当前所有的运行信息,返回 yiled 的值,并在下一次执行next()方法时从当前的位置继续运行
调用一个生成器函数,默认不会执行函数体,返回的是一个迭代器对象
def func():
print(
"哇哈哈")
yield 1
# return和yiled都能返回数据
print(
"呵呵呵")
gen =
func()
# 函数中如果有yield 这个函数就是生成器函数,生成器函数生成的是生成器,这个时候不执行函数
# yield:相当于return可以返回数据,但是yield不会彻底中断函数。分段执行
gen.
__next__()
# 执行函数,执行到下一个yield
gen.
__next__()
# 继续执行到下一个yield 如果没有则会报错 gen.__next__() StopIteration
1. 生成器的作用
举例需求:
当商店需要1W套学士服以备后面的使用:
def cloth():
lst =
[]
for i
in range(0, 10000
):
lst.append("衣服"+
str(i))
return lst
cl = cloth()
这样的结果是生产商一次将1W套学士服都给商家,商家不一次性全部卖出的话就会堆积仓库,最好的方式就是商家要一套,生产商给一套,一共1W套:
def cloth():
for i
in range(0, 10000
):
yield "衣服"+
(i)
cl =
cloth()
print(cl.
__next__())
print(cl.
__next__())
print(cl.
__next__())
区别是:第一种是直接一次性全部拿出来,会很占内存。第二种使用生成器,一次就用一个。用多少生成多少,生成器是一个一个的指向下一个。不会回去,__next__()到哪里,指针就指到哪里.下一次继续获取指针指向的值.
由此我们可以反应出生成器的那几个特点:
- 惰性机制
- 节省内存
- 只能向前
2. send()函数
同__next__()一样都可以让生成器执行到下一个yied。
# send 函数
def num():
print(
"1")
a =
yield "2"
print(
"a=", a)
b =
yield "3"
print(
"b = ", b)
c =
yield "4"
print(
"c = ", c)
yield "END"
gen = num()
# 获取生成器
ret1 = gen.
__next__()
print(ret1)
ret2 = gen.send(
"5")
print(ret2)
ret3 = gen.send(
"6")
print(ret3)
ret4 = gen.send(
"7")
print(ret4)
E:\Anaconda\python.exe F:/训练/8.13/
Train.py
1
2
a= 5
3
b = 6
4
c = 7
END
send和__next__()区别:
- send和__next__()都是让生成器向下走一次
- send可以给上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器代码的时候哦不能使用send()
3. 循环:
生成器可以使用for循环来循环获取内部的元素:
def func():
print(
"1")
yield "2"
print(
"3")
yield "4"
print(
"5")
yield "6"
print(
"7")
yield "8"
gen =
func()
for i
in gen:
print(i)
转载于:https://www.cnblogs.com/jiumo/p/9457582.html