iterable:可迭代的------对应的标志python
什么叫迭代?:一个一个取值,就像for循环同样取值bash
字符串,列表,元组,集合,字典都是可迭代的app
迭代器大部分都是在python的内部去使用的,咱们直接拿来用就好了函数
迭代器的优势:若是用了迭代器,节约内存,方便操做ui
dir([1,2].iter())是列表迭代器中实现的全部的方法,而dir([1,2])是列表中实现的全部方法,都是以列表的方式返回给咱们,为了方便看清楚,咱们把他们转换成集合,而后取差集,然而,咱们看到列表迭代器中多出了三个方法,那么这三个方法都分别是干什么的呢?spa
print(dir([1,2].__iter__()))#查看列表迭代器的全部方法
print(dir([1,2]))#查看列表的全部方法
print(set(dir([1,2].__iter__()))-set(dir([1,2])))
复制代码
iter_l=[1,2,3,4,5,6].__iter__()
print(iter_l.__length_hint__())#获取迭代器中元素的长度
print(iter_l.__setstate__(4))#根据索引指定从哪里开始迭代
print(iter_l.__next__())
print(iter_l.__next__())
print(iter_l.__next__())#一个一个的取值
print(next(iter_l))
#next(iter_l)这个方法和iter_l.__next__()方法同样,推荐用next(iter_l)这个
复制代码
l=[1,2,3,4,5]
a=l.__iter__()
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a)) #上面的列表长度只有5个,而你多打印了,就会报错。处理的状况以下,就不会报错了
while True:
try:
item=a.__next__()
print(item)
except StopIteration: ## 异常处理
break
复制代码
第一种:判断内部是否是实现了__next__方法code
'__iter__' in dir(str)#若是__iter__在这个方法里面,就是可迭代的。
复制代码
第二种: Iterable 判断是否是可迭代对象 Iterator 判断是否是迭代器 用法:对象
from collections import Iterable
from collections import Iterator
#好比给一个字符串
s='abc'
print(isinstance(s,Iterable))#isinstance判断类型的
print(isinstance(s,Iterator))
复制代码
判断range函数和map函数索引
map1=map(abs,[1,-2,3,-4])
print(isinstance(map1,Iterable))
print(isinstance(map1,Iterator))#map方法自带迭代器
s=range(100)#是一个可迭代的,可是不是迭代器
print(isinstance(s,Iterable))
print(isinstance(s,Iterator))
复制代码
python中提供的生成器:1.生成器函数 2.生成器表达式 生成器的本质:就是一个迭代器内存
def func(): #这是一个简单的函数
a=1
return a
print(func())
def func():
print('aaaaaaaaaaa')
a = 1
yield a ## 返回第一个值
print('bbbbbb')
yield 12 ## 返回第二个值
ret = func() ## 得拿到一个生成器
## print(ret)#返回的是一个地址
print(next(ret))#取第一个值
print(next(ret))## 取第二个值
print(next(ret))## 取第三个值,会报错,由于没有yield第三个值
复制代码
假如我想让工厂给学生作校服,生产2000000件衣服,我和工厂一说,工厂应该是先答应下来,而后再去生产,我能够一件一件的要,也能够根据学生一批一批的找工厂拿。 而不能是一说要生产2000000件衣服,工厂就先去作生产2000000件衣服,等回来作好了,学生都毕业了。。 作衣服
def make_cloth():
for i in range(1,20000):
yield '第%s件衣服'%(i)
ret = make_cloth()
print(next(ret))
print(next(ret))
print(next(ret))
for i in range(100):
print(next(ret))
复制代码
计算移动平均值
#必须先用next再用send
def average():
total=0 #总数
day=0 #天数
average=0 #平均数
while True:
day_num = yield average #average=0
total += day_num
day += 1
average = total/day
avg=average() #直接返回生成器
next(avg)#激活生成器,avg.send(),什么都不传的时候send和next的效果同样
print(avg.send(10))
print(avg.send(20))#send 1.传值 2.next
print(avg.send(30))
复制代码
带装饰器的计算移动平均值
让装饰器去激活
def wrapper(func):
def inner(*args,**kwargs):
ret = func(*args,**kwargs)
next(ret)
return ret
return inner
@wrapper
def average():
total=0 #总数
day=0 #天数
average=0 #平均数
while True:
day_num = yield average #average=0
total += day_num
day += 1
average = total/day
ret=average() #直接返回生成器
print(ret.send(10))
print(ret.send(20))#send 1.传一个值过去 2.让当前yield继续执行
print(ret.send(30))
复制代码
生成器监听文件例子
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)
复制代码
def func():
## for i in 'AB':
## yield i
yield from 'AB' yield from 'AB'就至关于上面的for循环,吧循环简化了
yield from [1,2,3]
g=func()
print(list(g))
## print(next(g))
## print(next(g))
yield from
复制代码
列表推导式
#举例一
y=2
#for i in range(100):
## print(i*y)
#列表推导式是for循环的简写
l=[i*y for i in range(100)]
复制代码
#举例二
l=[{'name':'v1','age':'22'},{'name':'v2'}]
## for dic in l:
## print(dic['name'])
name_list=[dic['name'] for dic in l]
print(name_list)
复制代码
一层循环
## ******一层循环******
l = [i*i for i in range(1,10)]
print(l)
## 上面的列表推倒式就至关于下面的
l = []
for i in range(1,10):
l.append(i*i)
print(l)
l = []
复制代码
多层循环
## 1.列表推倒式
l = [i*j for i in range(1,10) for j in range(1,10)]
print(l)
## 2.循环
l = []
for i in range(1,10):
for j in range(1,10):
s = i*j
l.append(s)
print(l)
复制代码
生成器表达
l=[{'name':'v1','age':'22'},{'name':'v2'}]
name_list=(dic['name'] for dic in l)#吧列表生成器的[]改为()
print(name_list)#取出的是一个生成器,而不是要取得值,因此得加上next
print(next(name_list))
print(next(name_list))
## print(next(name_list))
复制代码