一、.迭代器
for 迭代变量 in 可迭代对象
每一次循环都会自动让
“迭代变量”指向“下一个元素” 。
从可迭代对象生成一个迭代器,迭代器 = iter(可迭代对象),下个值 = next(迭代器)
for 实现原理
1.1 可迭代对象的判断
#1.for
#2.‘iter’
li = [1, 2, 3, 4, 5]
print(dir(li)) # ‘iter’
`1.2 迭代器:容器,将可迭代对象通过iter包起来
li = [1, 2, 3] # 可迭代对象
a = iter(li) # 迭代器
print(a) # <list_iterator object at 0x00000278AE9AB080>
迭代器如何取值
print(next(a)) # 每next一次,取一个值,注意取值次数不能超过可迭代对象的数量,超出报StopIteration错
print(next(a))
print(next(a))
#print(next(a)) # StopIteration
迭代协议
##### 迭代器特定
1.仅仅只需在迭代到某个元素时才计算该元素,而在这之前或者之后,元素可以不存在或者被销毁,适合于遍历一些巨大的或者无限的集合
2.不能回退
3.不能随机访问值
li = [1, 2, 3] # 可迭代对象
a = iter(li) # 迭代器
print(dir(li)) # 有"iter", 可迭代对象
print(dir(a)) # 有"iter"和"next", 迭代器
1.4 for循环如何实现迭代
li = [1, 2, 3] # 可迭代对象
for i in li:
print(i)
for实现迭代原理
li = [1, 2, 3] # 可迭代对象
itr = iter(li) # 迭代器
print("==="*15)
try:
while True:
b = next(itr)
print(b)
except StopIteration:
pass
Python将关键字in后的对象调用iter函数获取迭代器,然后通过调用迭代器的next方法获取元素,直到抛出StopIteration异常。
1.5 自定义可迭代对象 __iter__
class Mylist:
pass
def iter(self):
return iter([1, 2, 3])
a = Mylist() # 实例化对象,可迭代对象?
for i in a:
print(i)
print(dir(a))
2.生成器:
更加优雅的自定义可迭代对象的方法:生成器
1)生成器 与 yield
特性一: 类似于函数的逻辑
特性二: 支持显式的 暂停 与 恢复
特性三: 隐式的支持迭代协议
2)语法
yield 一个对象 ——————》返回这个对象 暂停这个函数 等待下次next重新激活
1.回忆函数
def func():
pass
func()
# 2.生成器定义,容器
def func():
yield 1
yield 3
yield 8
g = func()
print(g) # 生成器对象<generator object func at 0x0000019591F4C1A8>
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g)) # StopIteration
2)暂停和恢复
def func():
print("1前")
yield 1
print("3前")
yield 3
print("8前")
yield 8
g = func()
# 执行
ret = next(g) # 执行函数,到yield中止
print("返回值1:", ret)
ret = next(g) # 执行函数,到yield中止
print("返回值2:", ret)
ret = g.__next__() # 执行函数,到yield中止
print("返回值3:", ret)
2)生成器的应用
def func(elem, n):
count = 0
while True:
if count < n:
yield elem # 函数内有yield,这个函数就是生成器函数
count += 1
else:
break
man = func("刘若英,我爱你", 100)
# print(next(man))
#
# for i in man:
# print(i)
# 生成器的本质还是一个迭代器。
3.推到表达式
# a = [1, 3, 5]
# for i in range(10):
# print(i)
a = [i for i in range(1, 11)]
print(a) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a = [i for i in range(1, 11, 2)]
print(a) # [1, 3, 5, 7, 9]
a = [i for i in range(1, 11, 2) if i > 5]
print(a) # [7, 9]
4.模块
4.1模块路径
import sys
for i in sys.path:
print(i) # 模块搜索路径
"""
F:\class49\lesson16 # 当前目录
F:\class49
D:\software\python\python36.zip
D:\software\python\DLLs
D:\software\python\lib # 内置模块存放处
D:\software\python
D:\software\python\lib\site-packages # 第三方模块存放处
C:\Program Files\JetBrains\PyCharm 2018.3.3\helpers\pycharm_matplotlib_backend
"""
2) 模块的导入
1.import … 直接
2.import … as … 导入以后,重新命名
3.from … import … 部分导入,模块内部的东西,而不要模块
sys.path 用于存放导入路径的列表
类似于环境变量中的 PATH
# 1.内置模块:
import keyword
# print(keyword.kwlist)
# 2.第三方模块:
# 安装方法:
"""
pip install tornado
py -2/3 -m pip install django
"""
import tornado.web
# 3.自建模块
# 第一种导入方式:直接导入需要的函数
from lib.index import register
register()
# 第二种导入方式:导入py文件
from lib import index
index.register()
index.login()
# 第三种导入方式:导入py文件,但使用另一个名字代替,方便代码开发
from lib import index as dd
dd.login()
4.3 其他目录下模块的导入
import sys
sys.path.append("E:")
import fei
fei.f()
# for i in sys.path:
# print(i)
from datetime import datetime
start = datetime.now()
print(type("hello"))
end = datetime.now()
start1 = datetime.now()
print(isinstance("hello", str))
end1 = datetime.now()
if end-start > end1-start1:
print("type慢")
else:
print("isinstance慢")
# 函数:代码复用
def func1():
start = datetime.now()
print(type("hello"))
end = datetime.now()
total = end - start
return total
def func2():
start1 = datetime.now()
print(isinstance("hello", str))
end1 = datetime.now()
total = end1 - start1
return total
if __name__ == '__main__':
res1 = func1()
res2 = func2()
if res1 > res2:
print("type慢")
else:
print("isinstance慢")
import time
# 类:
class Test:
def fun1(self):
self.start = datetime.now()
time.sleep(5)
def fun2(self):
self.end = datetime.now()
total = self.end - self.start
print(total)
res = fun1()
fun2(res) # 0:00:05.000609
5.包
对于自建模块,当开发项目时,在project文件夹下创建lib文件夹专门存放(编程规范)
模块是什么?模块是py文件,那包呢,就是包含了很多模块的文件夹,比如上面的lib文件夹。