Python–13、迭代器,生成器和包管理
迭代器
迭代
可迭代对象(iterable):列表、元组、字符串、字典。
迭代:通过重复执行代码用来处理类似的数据的过程。迭代的过程是指依次从数据结构中拿出东西的过程。
while也能实现拿取,只是需要自己控制下标。
#迭代器 iterator
#实现了迭代的方式的容器
li = [1,2,3,4,5,6,'a','b','c']
a = iter(li) #定义迭代器,标志li是一个可迭代对象
print(dir(a)) #__iter__/__next__
#next:单词只能取一个a中的值
print(next(a))
print(next(a))
print('------')
for i in a:
print(i)
for 迭代变量 in 可迭代变量。
每一次循环都会自动让“迭代变量”指向下一个元素。
迭代器 = iter(可迭代对象)
下个值 = next(迭代器)
对于迭代器里面的内容,使用for … in …也可进行取值。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W2o10Bxf-1580116248476)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200109203646257.png)]
使用print(next(iter)) 进行连续取值时,如果超出范围就会强制停止。这里可以与while True :进行搭配。但是强制退出的时候会提示StopIteration,可以使用try…except… 进行搭配。
迭代器的优势:
数列的数据量庞大;消耗性容器;对于某些有规律但使用列表生成器无法取值的数。
li = [1,2,3,4,5,6,'a','b','c']
itr = iter(li)
#实现和for... in ...一样的功能
try:
while True:
b = next(itr)
print(b)
except StopIteration:
pass
运行结果:
1
2
3
4
5
6
a
b
c
迭代器的重写方式:
class MyList:
def __init__(self):
self.li = [1,2,3,4,5,6]
self.index = 0
def __iter__(self): #必须返回一个迭代器
return iter(self.li)
def __next__(self):
num = self.index
self.index += 1
return self.li[num]
n1 = MyList()
try:
while True:
b = next(n1)
print(b)
except StopIteration:
pass
except IndexError:
pass
列表生成器
#列表生成式
L = [x for x in range(10)]
print(L)
#for 循环原理
li = [1,2,3,4,5,6,'a','b','c']
index = 0
while index < len(li):
res = li[index]
print(res)
index +=1
生成器
生成器功能
不断产生新的值。一边循环,一边计算。类似于列表推导式,只是用圆括号代替了方括号而已。
与普通函数不同,生成器函数的局部变量值会保存下来,从本次调用保留至下一次调用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGA6LIzq-1580116248476)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200110160156974.png)]
#生成器
g =(x for x in range(10))
print(g)
#列表创建数据的话,要全部写出才可以用。对于多条数据会不方便
#对于不用的数据,生成器并不会进行运算,只有使用时才会计算出值
#一边循环,一边计算
print(next(g))
print(next(g))
for i in g:
print(i)
#函数这里会继续往下走
运行结果:
0
1
2
3
4
5
6
7
8
9
yield函数
带有yield的函数是一个迭代器,函数返回某个值时,会停留在某个位置,返回函数值后,会在前面停留的位置继续执行,直到程序结束。
应用:对于分步拿取的爬虫。
def func():
print('这是1 ')
yield 1
print('这是2 ')
yield 2
print('这是3 ')
yield 3
return 0 #完全停止并返回,之后的内容不会再执行,标志函数的完全结束
print("不会被打印出来")
n2 = func()
print(next(n2))
print(next(n2))
运行结果:
这是1
1
这是2
2
for i in n2: #可以每一个都打印
print(i)
class Mylist:
def __iter__(self):# 返回的一个生成器
print('生成自定义数据,不确定数量')
return iter([1,2,3])
yield from
yield from 函数使生成器和函数串联起来。执行方式和yield相同,但是会将生成请求委托给子生成器。
>>> def subgen(x):
for i in range(x):
yield i
>>> def gen(y):
yield from subgen(y)
>>> for q in gen(6):
print(q)
0
1
2
3
4
5
斐波切拉函数
#斐波拉切函数
#递归形式实现,自上而下的形式
def fib(n):
if n ==1 or n == 2:
return 1
else:
return fib(n-1)+fib(n-2)
print(fib(2))
#生成器形式 计算
import time
def fib1(n):
a = 0
b = 1
i = 0
while i<10:
a,b = b,a+b #Python变量值的交换,相加对前两项的和
i += 1
yield a #暂停并返回
res = fib1(10)
for i in res:
time.sleep(1)
print(i)
包管理
导入模块/库/包
模块:一个Python文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BqwF8vlu-1580116248477)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200110161211161.png)]
导入方式
import … 直接
import … as … 导入以后,重新命名
from … import … 部分导入,模块内部的东西,而不要模块(可以使用 *代指全部)
sys.path 用于存放导入路径的列表,类似于环境变量的的PATH
sys.argv 查看当前文件路径
__ pycache __ 缓存文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dnE9nYJR-1580116248477)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200110163008742.png)]
导入自定义 模块
1、直接import
大前提:执行的py文件和模块同属于同个目录(父级目录)。
2、使用sys.path() 方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ve2ShYHB-1580116248477)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200112110110373.png)]
. 部分导入,模块内部的东西,而不要模块(可以使用 *代指全部)
sys.path 用于存放导入路径的列表,类似于环境变量的的PATH
sys.argv 查看当前文件路径
__ pycache __ 缓存文件
[外链图片转存中…(img-dnE9nYJR-1580116248477)]
导入自定义 模块
1、直接import
大前提:执行的py文件和模块同属于同个目录(父级目录)。
2、使用sys.path() 方法
[外链图片转存中…(img-ve2ShYHB-1580116248477)]