可迭代对象
字符串,列表,元组,字典,集合都是可以使用for循环遍历,当然,他们也是可迭代的。我觉得,for循环没有特别大的用处,它的用处就是用来循环遍历那些可迭代对象的。isinstance用来可以用来证明是可迭代的对象
from collections import Iterable
l = [1,2,3,4]
t = (1,2,3,4)
d = {1:2,3:4}
s = {1,2,3,4}
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))
执行结果:
True
True
True
True
优点
使用迭代器,节约了内存,方便了操作
可迭代协议
满足迭代的要求就是可迭代的对象,其实说白了就是该对象有__iter__方法。
print(dir([1,2]))
print(dir((2,3)))
print(dir({1:2}))
print(dir({1,2}))
执行结果:
[‘add’, ‘class’, ‘contains’, ‘delattr’, ‘delitem’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘gt’, ‘hash’, ‘iadd’, ‘imul’, ‘init’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘mul’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘reversed’, ‘rmul’, ‘setattr’, ‘setitem’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘append’, ‘clear’, ‘copy’, ‘count’, ‘extend’, ‘index’, ‘insert’, ‘pop’, ‘remove’, ‘reverse’, ‘sort’]
[‘add’, ‘class’, ‘contains’, ‘delattr’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘getnewargs’, ‘gt’, ‘hash’, ‘init’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘mul’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘rmul’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘count’, ‘index’]
[‘class’, ‘contains’, ‘delattr’, ‘delitem’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘gt’, ‘hash’, ‘init’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘setitem’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘clear’, ‘copy’, ‘fromkeys’, ‘get’, ‘items’, ‘keys’, ‘pop’, ‘popitem’, ‘setdefault’, ‘update’, ‘values’]
[‘and’, ‘class’, ‘contains’, ‘delattr’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘gt’, ‘hash’, ‘iand’, ‘init’, ‘ior’, ‘isub’, ‘iter’, ‘ixor’, ‘le’, ‘len’, ‘lt’, ‘ne’, ‘new’, ‘or’, ‘rand’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘ror’, ‘rsub’, ‘rxor’, ‘setattr’, ‘sizeof’, ‘str’, ‘sub’, ‘subclasshook’, ‘xor’, ‘add’, ‘clear’, ‘copy’, ‘difference’, ‘difference_update’, ‘discard’, ‘intersection’, ‘intersection_update’, ‘isdisjoint’, ‘issubset’, ‘issuperset’, ‘pop’, ‘remove’, ‘symmetric_difference’, ‘symmetric_difference_update’, ‘union’, ‘update’]
‘’‘从这里面就是输出就是这些对象可以使用的方法’’’
可迭代的:内部必须含有一个__iter__方法。
迭代器
l = [1, 2, 3, 4, 5]
l_iter = l.__iter__()#建可迭代的转化为迭代器
item = l.__iter__().__next__()
print(item)
item = l.__iter__().__next__()
print(item)
从上面我们可以看出,迭代器遵循迭代器协议,说白了就是iter next 的方法。
可以用while循环模拟for循环,这样,也可以有利于帮助自己理解iter 方法
l = [1, 2, 3, 4, 5]
l_iter = l.__iter__()
while True:
try:
item = l.__iter__().__next__()
print(item)
except StopIteration:
break
需要说明两点:
可迭代和迭代器具有相同点;都可以进行for循环
可迭代和迭代器具有不同点;迭代器内部多实现了一个__next__方法
判断迭代器和可迭代的方法:
1.判断内部是不是实现了__next__方法
2 .Iterable 判断是不是可迭代对象
Iterator 判断是不是迭代器
生成器
迭代器有两种:一、调用方法直接返回,一种 可迭代对象通过执行iter方法得到的,迭代器有的好处是可以节省内存。
但有时,需要节省内存,但是你自己的需求就需要你自己写,自己写的就叫生成器
生成器函数:他依然还是个自定义的函数,只是使用yield返回结果,而不是return,yield语句返回是挂起状态,你自己也可以理解为它的函数结束后,不是直接销毁,而是像进程一样处于挂起状态,下次再执行的时候,它会从上一次的地方再开始执行,返回的结果是一个对象,而不是一个结果列表
python中提供的生成器:1.生成器函数 2.生成器表达式
生成器函数
import time
def genrator_fun1():
a = 1
print('现在定义了a变量')
yield a
b = 2
print('现在又定义了b变量')
yield b
g1 = genrator_fun1()
print('g1 : ',g1) #打印g1可以发现g1就是一个生成器
print('-'*20)
print(next(g1))
time.sleep(1)
print(next(g1))
生成器最大的好处就是节省空间,不会一下子产生大量的数据
给出一个例子,也是从别的地方看到的:
#生成器监听文件
import time
def tail(filename):
f = open(filename)
f.seek(0, 2) #从文件末尾算起
while True:
line = f.readline() # 读取文件中新的文本行
if not line:
time.sleep(0.1)
continue
yield line
tail_g = tail('tmp')
for line in tail_g:
print(line)
send
def generator():
print(123)
content = yield 1
print('=======',content)
print(456)
yield2
g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello') #send的效果和next一样
print('***',ret)
#send 获取下一个值的效果和next基本一致
#只是在获取下一个值的时候,给上一yield的位置传递一个数据
#使用send的注意事项
# 第一次使用生成器的时候 是用next获取下一个值
# 最后一个yield不能接受外部的值