十,迭代器和生成器
迭代器
迭代:
-
依次从数据结构拿出东西的过程
此为容器,将可迭代的对象通过iter(可迭代对象)包起来
# 迭代器:容器,将可迭代对象通过iter包起来
li = [1, 2, 3, 4, 5]
a = iter(li) # 迭代器
print(a)
# 迭代器的取值
print(next(a))
print(next(a))
print(next(a))
"""
next
- 访问者不需要去关心内部结构,只需要通过next不断去取下一个内容
- 只能从头到尾依次访问,不能回退
- 便于循环比较大的数据集合,节省内存
可迭代对象和迭代器的区别:
有无 next 方法的使用
li = [1, 2, 3, 4, 5]
print(dir(li)) # '__iter__'
a = iter(li)
print(dir(a)) # '__iter__', '__next__'
for 迭代器
a = iter(li)
for i in a:
print(i)
自定义可迭代对象
class Mylist:
def __iter__(self):
return iter([1, 2, 3, 4, 5])
a = Mylist() # 实例化对象,可迭代对象
for i in a:
print(i)
生成器
自定义可迭代对象,更优雅的方式------生成器
生成器定义
类似函数逻辑
def func1(): # 容器
yield 1
生成器的取值
def f():
yield 1
yield 5
yield 8
g = f()
print(g) # <generator object f at 0x000001E3C337C1A8>生成器对象
for i in g:
print(i)
暂停和恢复
def f():
print(1)
yield 5
print(2)
yield 9
print(3)
yield 8
g = f() # 生成器对象
# 取值
res = next(g) # 执行函数,至yield中止,返回yield后面的值,结果:1
print(res) # 结果:5
res = next(g) # 从上次中止位置开始执行函数,至下一个yield中止,结果:2
print(res) # 结果:9
实例的应用:
import time #导入 time 模块
# 应用:列表占内存,生成器只有取用的时候才会生成这个元素,加载到内存里
def f(con, n):
count = 0
while True:
if count < n:
yield con # 生成器函数
count += 1
else:
break
man = f("legacy", 10)
# 取值
for i in man:
print(i)
time.sleep(2) #time 模块的方法 间隔 2秒输出
# 生成器:自定义迭代器更优雅的方式,本质还是一个迭代器
总结:
1.可迭代对象:for + iter
2.迭代器:iter(可迭代对象),for + iter+next
3.生成器:自定义迭代器更优雅的方式,本质还是一个迭代器for + iter+next
推倒的表达式
a = [i for i in range(10)]
print(a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
循环嵌套的简写表达式
for i in range(10):
for j in range(10):
print(i, j)
b = [[j for j in range(10)] for i in range(10)]
print(b)
十一,模块,导入,包
导入模块
import sys
for i in sys.path:
print(i) #输出python解释器对模块位置的搜索顺序和本地路径
模块的导入
# 1.内置模块:
import random
print(random.random())
# 2.第三方模块:
# 安装: pip 等方法
# 导入
import tornado.web # tornado模块导入例子
自建模块
模块----》py文件
包----》存放模块的文件夹,__ init __.py
导入
# 1.直接导入我们需要的自建函数
from lib.index import login
login()
# 2.导入py文件
from lib import index
index.login()
index.logout()
# 3.导入py文件,起别名,方便代码的开发
from lib import index as dd
dd.login()
dd.logout()
# 4.使用import导入,需要写全
import lib.index
lib.index.login()
lib.index.logout()
拓展:
自建模块函数添加到python解释器对模块位置的搜索顺序:
import sys
sys.path.append(r"E:\fei\讲义\1-基础班") #添加到python解释器对模块位置的搜索顺序
for i in sys.path:
print(i) #查看是否添加成功
import buy #导入自己写的模块函数
buy.count() #调用自己写的函数
十二,正则表达式
元字符
元字符分别有 . * ? + [] () \ ^ $
使用格式:
re.findall(pattern, string, flag=0)
例:
s1 = 'testing123'
s2 = 'Testing123'
r = re.findall("test", s1)
print(r) # ['test'] 这个的输出的类型为列表
r = re.findall("test", s2)
print(r) #此处 没有 test 是一个空列表 输出 因为这个严格按照你的条件搜索 因为是大写所以不输出
1.普通字符
修饰符 re.I 忽略大小写
r = re.findall("test", s, re.I) #['test', 'Test']
2. . 通配符
匹配除了“\n”以外的任何单个字符;
修饰符 re.S 使 . 匹配包括换行符在内的所有字符
s = 'testing123\nTesting123'
r = re.findall(".", s)
print(r) #把这个字符串的字母作为一个个元素储存在一个列表里 但不包括 \n(换行符)
r = re.findall(".", s, re.S)
print(r) #把这个字符串的字母作为一个个元素储存在一个列表里 包括 \n(换行符)
3.^
匹配输入字符串的开头位置
修饰符 re.M 多行匹配
OR(|):或,多个修饰符通过它来指定
s = 'testing123\nTesting123\ntest'
r = re.findall("^test", s) #则意思为 字符串开头必须是 test 否则找不到
r1 = re.findall("^test", s, re.M)
r2 = re.findall("^test", s, re.I | re.M)
print(r) #['test']
print(r1) #['test', 'test']
print(r2) #['test', 'Test', 'test']
4.$
匹配输入字符串的结束位置
s = 'testing123\nTesting123\ntest'
r = re.findall("tes3$", s)
print(r) #['test']
r = re.findall("testing123$", s, re.M)
print(r) #['testing123']
r = re.findall("testing123$", s, re.M | re.I)
print(r) #['testing123', 'Testing123']
5. * +?
匹配前面的子表达式任意次/大于等于1次/零次或一次
{ }匹配前面的子表达式
s1 = "z\nzo\nzoo"
r = re.findall("zo*", s1)
r1 = re.findall("zo{0,}", s1)
print("r", r) #['z', 'zo', 'zoo']
print("r1", r1) #['z', 'zo', 'zoo']
r = re.findall("zo+", s1)
r1 = re.findall("zo{1,}", s1)
print("r", r) #['zo', 'zoo']
print("r1", r1) #['zo', 'zoo']
r = re.findall("zo?", s1)
r1 = re.findall("zo{0,1}", s1)
print("r", r) #['z', 'zo', 'zo']
print("r1", r1) #['z', 'zo', 'zo']
r1 = re.findall("zo{2}", s1)
print(r1) # ['zoo']
6.[] 字符组
字符组:内容
s = "test\nTesting\nzoo"
r = re.findall("[oet]", s) # 匹配[]包含的字符
print("oet", r) #['t', 'e', 't', 'e', 't', 'o', 'o']
r = re.findall("[e-i]", s) #包含在此字符串 e到i的所有的字母 作为列表元素出
print(r) #['e', 'e', 'i', 'g']
r = re.findall("^[oet]", s) #开头必须是 o e t 其中一个才能输出
print(r) #['t']
r = re.findall("[^oet]", s) #匹配[]未包含的字符
print("^oet", r) #['s', '\n', 'T', 's', 'i', 'n', 'g', '\n', 'z']
r = re.findall("[^e-i]", s) # 匹配 e到i 未包含的字符
print(r) #['t', 's', 't', '\n', 'T', 's', 't', 'n', '\n', 'z', 'o', 'o']
7. |
选择元字符
s = "z\nzood\nfood"
r = re.findall("z|food", s) # 匹配z或food
print(r) #['z', 'z', 'food']
r = re.findall("[z|f]ood", s) # 匹配zood或food
print(r) #['zood', 'food']
r = re.findall("[zf]ood", s) # 匹配zood或food
print(r) #['zood', 'food']
8. ()
分组元字符
s = "z\nzood\nfood"
r = re.findall("[zf]o*", s) #*的用法 代表了任意个o
print(r) #['z', 'zoo', 'foo']
r1 = re.findall("[zf](o*)", s) #只返回括号里的
print(r1) #['', 'oo', 'oo']
9. /
字符串的转义
s1 = "z\nzo\nzoo"
print(s1) #输出为 z换行 zo换行 zoo
s2 = r"z\nzo\nzoo" #字符串的转义
print(s2) #输出为 z\nzo\nzoo
s3 = "z\\nzo\\nzoo" #加上 \ 使换行符转为普通的\n字符
print(s3) #输出为 z\nzo\nzoo
贪婪模式和非贪婪模式
非贪婪模式 .*?:尽可能少的匹配字符
贪婪模式和非贪婪模式的对比
import re #记得导入re库
r = re.findall("ab.*c", s) # 贪婪模式.*/.+, 尽可能多的匹配字符
print(r) #['abcabdadcaec']
r1 = re.findall("ab.*?c", s) # 非贪婪模式:尽可能少的匹配字符
print(r1) #['abc', 'abdadc']
预定义字符类
预定义字符类 | 说明 | 对等字符类 |
---|---|---|
\d | 得到目标的所有数字字符 | [0-9] |
\D | 得到目标的非数字字符 | [^0-9] |
\s | 得到目标的空白符如换行 制表符 | [\t\n\x0B\f\r] |
\S | 得到目标的非空白符 | [^\t\n\x0B\f\r] |
\w(小) | 得到目标的字母和数字字符 | [a-zA-Z0-9] |
\W(大) | 得到目标的非字母和数字字符 | [^a-zA-Z0-9] |
正则函数
re库里有 findall match search此为正则函数
findall(pattern, string):
将匹配到的全部内容放入一个列表返回
s = "Cats are Cat"
r1 = re.findall("C\w+", s)
r2 = re.findall("(C\w+)", s)
r3 = re.findall("C(\w+)", s)
r4 = re.findall("(C)(\w+)", s)
print(r1) # ['Cats', 'Cat']
print(r2) # ['Cats', 'Cat']
print(r3) # ['ats', 'at']
print(r4) # [('C', 'ats'), ('C', 'at')]
match(pattern, string):
从头匹配(如果字符串的开始不符合表达式,匹配失败)
s = "Cats are Cat"
r = re.match("C\w+", s)
print(r.group()) # 获取匹配到的值Cats
print(r.groups()) # 获取匹配到的分组
r = re.match("(C)(\w+)", s)
print(r.group()) # 获取匹配到的值Cats
print(r.groups()) # 获取匹配到的分组
search(pattern, string):
浏览全部的字符 只返回匹配到的第一个
s = "cats are Cat"
r = re.search("C\w+", s)
print(r.group()) # 获取匹配到的值Cats
print(r.groups()) # 获取匹配到的分组
r = re.search("(C)(\w+)", s)
print(r.group()) # 获取匹配到的值Cats
print(r.groups()) # 获取匹配到的分组