破解WordPress站点,drupal wordpress,代刷网址推广,威海北京网站建设文章目录1. 迭代器2. 生成器3. 标准库3.1 过滤3.2 映射3.3 合并3.4 排列组合3.5 重新排列4. yield from5. 可迭代的归约函数6. iter 还可以传入2个参数7. 生成器当成协程learn from 《流畅的python》
1. 迭代器
所有生成器都是迭代器#xff0c;因为生成器完全实现了迭代器接…
文章目录1. 迭代器2. 生成器3. 标准库3.1 过滤3.2 映射3.3 合并3.4 排列组合3.5 重新排列4. yield from5. 可迭代的归约函数6. iter 还可以传入2个参数7. 生成器当成协程learn from 《流畅的python》
1. 迭代器
所有生成器都是迭代器因为生成器完全实现了迭代器接口序列可以迭代的原因iter函数解释器需要迭代对象 x 时会自动调用 iter(x)内置的 iter先检查是否实现了 __iter__不然检查是否实现 __getitem__并创建迭代器
标准的迭代器接口有两个方法
__next__ 返回下一个可用的元素如果没有元素了抛出 StopIteration 异常__iter__ 返回 self以便在应该使用可迭代对象的地方使用迭代器例如 在 for 循环中
不要在可迭代对象的类中实现迭代器一举两得错误大佬教我不要这么做
为了支持多种遍历需要获取独立的多个迭代器每次调用 iter() 都创建独立的迭代器对象 可迭代的对象 一定不能 是 自身的迭代器 也就是说可迭代的对象 必须实现 __iter__ 方法但不能实现 __next__ 方法 2. 生成器
只要 Python 函数的定义体中有 yield 关键字该函数就是生成器函数 调用生成器函数时会返回一个生成器对象
惰性获取匹配项 re.finditer 可以节省内存和无效工作
生成器表达式可以理解为列表推导的惰性版本按需 惰性生成元素
def genAB():print(start)yield Aprint(continue)yield Bprint(end)ans1 [x*2 for x in genAB()] # 循环迭代列表推导生成的 ans1 列表
# 输出以下内容
# start
# continue
# endfor x in ans1:print(x)
# 输出
# AA
# BBans2 (x*2 for x in genAB()) # 生成器表达式会产出生成器ans2 是一个生成器对象
# 无输出for x in ans2: # 调用时才真正执行 genAB 函数产出数值print(x)
# 输出
# start
# AA
# continue
# BB
# end3. 标准库
import itertools
gen itertools.count(5, 0.5)
print(next(gen))
print(next(gen))
print(next(gen))
# 5
# 5.5
# 6.0list(count()) 会生成无穷的序列内存会爆炸
gen itertools.takewhile(lambda n : n 6, itertools.count(5, 0.5))
print(list(gen)) # [5, 5.5]takewhile 不满足条件时退出
3.1 过滤 def vowel(c):return c.lower() in aeiouprint(list(filter(vowel, Abcdea))) # [A, e, a]
print(list(itertools.filterfalse(vowel, Abcdea))) # [b, c, d]
print(list(itertools.dropwhile(vowel, Aardvark)))
# [r, d, v, a, r, k] 遇到不满足的即停止检测
print(list(itertools.takewhile(vowel, Aardvark)))
# [A, a] 遇到不满足的即停止检测
print(list(itertools.compress(Aardvark, (1, 0, 1, 1, 0, 1))))
# 产出后者是真值的前者元素 [A, r, d, a]
print(list(itertools.islice(Aardvark, 4)))
# [A, a, r, d] 前 4 个元素
print(list(itertools.islice(Aardvark, 4, 7)))
# [v, a, r] [4,7) 的元素
print(list(itertools.islice(Aardvark, 1, 7, 2)))
# [a, d, a] [1,7) 每 2 个 取一个3.2 映射 sample [9, 5, 4, 6, 8, 9]
print(list(itertools.accumulate(sample)))
# [9, 14, 18, 24, 32, 41] 累加求和前缀和
print(list(itertools.accumulate(sample, min)))
# [9, 5, 4, 4, 4, 4] 累积的最小值
print(list(itertools.accumulate(sample, max)))
# [9, 9, 9, 9, 9, 9]
print(list(itertools.accumulate(sample, operator.mul)))
# [9, 45, 180, 1080, 8640, 77760] 前缀乘积
print(list(itertools.accumulate(range(1, 11), operator.mul)))
# [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]print(list(enumerate(abc, start2)))
# [(2, a), (3, b), (4, c)]
print(list(map(operator.mul, range(11), range(1, 11))))
# x*(x1) 对应相乘元素少的结束即停止
print(list(map(lambda a, b: (a, b), range(11), [2, 4, 8])))
# [(0, 2), (1, 4), (2, 8)] 等效于 zip 函数
print(list(itertools.starmap(operator.mul, enumerate(abc, 1))))
# [a, bb, ccc]
sample [2, 3, 4, 5]
print(list(itertools.starmap(lambda a, b: b / a, enumerate(itertools.accumulate(sample), 1))))
# 求累积 均值 [2.0, 2.5, 3.0, 3.5]3.3 合并 print(list(itertools.chain(ABC, range(5))))
# [A, B, C, 0, 1, 2, 3, 4] , 可传入多个可迭代对象
print(list(itertools.chain(enumerate(ABC))))
# [(0, A), (1, B), (2, C)] 传入一个参数没啥用
print(list(itertools.chain.from_iterable(enumerate(ABC))))
# 只接收一个参数且对象是可迭代的
# [0, A, 1, B, 2, C]
print(list(zip(ABC, range(5))))
# [(A, 0), (B, 1), (C, 2)] 短的先结束
print(list(zip(ABC, range(5), [10, 20, 30, 40])))
# [(A, 0, 10), (B, 1, 20), (C, 2, 30)] 课输入多个参数
print(list(itertools.zip_longest(ABC, range(5))))
# [(A, 0), (B, 1), (C, 2), (None, 3), (None, 4)], 以最长的为结束
print(list(itertools.zip_longest(ABC, range(5), fillvalue?)))
# [(A, 0), (B, 1), (C, 2), (?, 3), (?, 4)] 填充默认值# 笛卡尔积惰性生成
print(list(itertools.product(ABC, range(2))))
# [(A, 0), (A, 1), (B, 0), (B, 1), (C, 0), (C, 1)]
print(list(itertools.product(ABC)))
# [(A,), (B,), (C,)] 传入一个参数得到只有一个元素的元组没啥用
print(list(itertools.product(ABC, repeat2)))
# [(A, A), (A, B), (A, C), (B, A), (B, B), (B, C), (C, A), (C, B), (C, C)]
# 相当于两重循环
print(list(itertools.product(range(2), repeat3)))
# [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
# 3 重循环
rows itertools.product(AB, range(2), repeat2)
for row in rows: print(row)
# (A, 0, A, 0)
# (A, 0, A, 1)
# (A, 0, B, 0)
# (A, 0, B, 1)
# (A, 1, A, 0)
# (A, 1, A, 1)
# (A, 1, B, 0)
# (A, 1, B, 1)
# (B, 0, A, 0)
# (B, 0, A, 1)
# (B, 0, B, 0)
# (B, 0, B, 1)
# (B, 1, A, 0)
# (B, 1, A, 1)
# (B, 1, B, 0)
# (B, 1, B, 1)
print(-----)
for a in AB:for b in range(2):for c in AB:for d in range(2):print((a, b, c, d))
# (A, 0, A, 0)
# (A, 0, A, 1)
# (A, 0, B, 0)
# (A, 0, B, 1)
# (A, 1, A, 0)
# (A, 1, A, 1)
# (A, 1, B, 0)
# (A, 1, B, 1)
# (B, 0, A, 0)
# (B, 0, A, 1)
# (B, 0, B, 0)
# (B, 0, B, 1)
# (B, 1, A, 0)
# (B, 1, A, 1)
# (B, 1, B, 0)
# (B, 1, B, 1) 跟上面结果一致ct itertools.count()
print(next(ct), next(ct), next(ct), next(ct), next(ct))
# 0 1 2 3 4
print(list(itertools.islice(itertools.count(1, .3), 3)))
# [1, 1.3, 1.6]
cy itertools.cycle(ABC)
print(next(cy), next(cy), next(cy), next(cy))
# A B C A, 产生元素的副本不断重复
print(list(itertools.islice(cy, 7)))
# [B, C, A, B, C, A, B]
rp itertools.repeat(7)
print(list(itertools.islice(rp, 10)))
# [7, 7, 7, 7, 7, 7, 7, 7, 7, 7]
print(list(itertools.repeat(8, 4)))
# [8, 8, 8, 8]
print(list(map(operator.mul, range(11), itertools.repeat(5))))
# [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50] 0-10 分别乘以53.4 排列组合
print(list(itertools.combinations(ABC, 2)))
# [(A, B), (A, C), (B, C)]
# 组合从中取出2个的方案数无序要求 C32
print(list(itertools.combinations_with_replacement(ABC, 2)))
# [(A, A), (A, B), (A, C), (B, B), (B, C), (C, C)]
# 组合无序可重复
print(list(itertools.permutations(ABC, 2)))
# [(A, B), (A, C), (B, A), (B, C), (C, A), (C, B)]
# 排列有顺序要求
print(list(itertools.product(ABC, repeat2))) # 的笛卡儿积
# [(A, A), (A, B), (A, C),
# (B, A), (B, B), (B, C),
# (C, A), (C, B), (C, C)]3.5 重新排列 print(list(itertools.groupby(LLLLAAGGG)))
# [(L, itertools._grouper object at 0x000001A6D638C460),
# (A, itertools._grouper object at 0x000001A6D6538E80),
# (G, itertools._grouper object at 0x000001A6D8F7EA00)]
for char, group in itertools.groupby(LLLLAAGGG):print(char, -, list(group))# L - [L, L, L, L]
# A - [A, A]
# G - [G, G, G]for char, group in itertools.groupby(ALLLLAAGGG):print(char, -, list(group))
# A - [A] # 没有相邻的A
# L - [L, L, L, L]
# A - [A, A]
# G - [G, G, G]animals [duck, eagle, rat, giraffe, bear, bat, dolphin, shark, lion]
animals.sort(keylen) # 按长度排序
print(animals)
# [rat, bat, duck, bear, lion, eagle, shark, giraffe, dolphin]
for length, group in itertools.groupby(animals, len):print(length, -, list(group))
# 3 - [rat, bat]
# 4 - [duck, bear, lion]
# 5 - [eagle, shark]
# 7 - [giraffe, dolphin]
for length, group in itertools.groupby(reversed(animals), len):print(length, -, list(group))
# 7 - [dolphin, giraffe]
# 5 - [shark, eagle]
# 4 - [lion, bear, duck]
# 3 - [bat, rat]
abc [apple, bear, animals, bull, lakers]
abc.sort()
for char, group in itertools.groupby(abc, lambda x: x[0]):print(char, -, list(group))
# 按首字母分组
# a - [animals, apple]
# b - [bear, bull]
# l - [lakers]# itertools.tee 函数产出多个生成器每个生成器都 可以产出输入的各个元素
# 默认2个后面可加参数 n 输出多个
print(list(itertools.tee(ABC)))
# [itertools._tee object at 0x000001D4AEEE8AC0,
# itertools._tee object at 0x000001D4AEEE8A80]
g1, g2 itertools.tee(ABC)
print(next(g1)) # A
print(list(g1)) # [B, C]
print(next(g2), next(g2)) # A B
print(list(g2)) # [C]
print(list(zip(*itertools.tee(ABC))))
# [(A, A), (B, B), (C, C)]4. yield from
yield from 语句的作用就是把不同的生成器结合在一起使用
def chain(*iterables):for it in iterables:for i in it:yield i
s ABC
t tuple(range(3))
print(list(chain(s, t)))
# [A, B, C, 0, 1, 2]def chain1(*iterables):for it in iterables:yield from it# 完全代替了内层的 for 循环
print(list(chain1(s, t)))
# [A, B, C, 0, 1, 2]5. 可迭代的归约函数 any, all 可以短路一旦确定结果就停止迭代也可以这样调用 max(arg1, arg2, ..., [key?])sorted 操作完成后返回排序后的 列表。它可以处理任意的可迭代对象
print(all([1, 2, 3])) # True
print(all([0, 2, 3])) # False
print(all([])) # True
print(any([1, 2, 3])) # True
print(any([0, 2, 3])) # True
print(any([0, 0.0])) # False
print(any([])) # False
g (n for n in [0, 0.0, 7, 8])
print(any(g)) # True 遇到7结束
print(list(g)) # [8] 还剩余86. iter 还可以传入2个参数
当遇到第二个参数时停止迭代
def d6():return random.randint(1, 6)d6_iter iter(d6, 1) # 无参函数 遇到1停止迭代
for roll in d6_iter:print(roll)
# 6
# 2
# 4
# 3
# 2
# 4
# 3
# 5
# 2
# 3
print(list(d6_iter)) # [] 耗尽了
d6_iter iter(d6, 1)
print(list(d6_iter)) # [4, 5, 3, 6, 2, 5, 4, 6, 5, 6, 6] 随机的这段代码逐行读取文件直到遇到空行或者到达文件末尾为止
with open(mydata.txt) as fp:for line in iter(fp.readline, \n):process_line(line)7. 生成器当成协程
.send() 方法后面会学到与 .__next__() 方法一样.send() 方法致使生成器前进到下一个 yield 语句.send() 方法还允许使用生成器的客户 把 数据 发给 自己即不管传给 .send() 方法什么参数那个参数都会 成为生成器 函数定义体中对应的 yield 表达式的值