当前位置:
首页 > temp > python入门教程 >
-
【Python】笔记:可迭代的对象、迭代器和生成器
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence_v1:
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text)
def __getitem__(self, index):
return self.words[index]
def __len__(self):
return len(self.words)
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
s = Sentence_v1('"The time has come," the Walrus said,')
print(repr(s))
for word in s:
print(word)
Sentence('"The time ha... Walrus said,')
The
time
has
come
the
Walrus
said
当解释器需要迭代对象时,
-
__iter__
-
__getitem__
-
抛出
TypeError
class Foo:
def __iter__(self):
pass
from collections import abc
print(issubclass(Foo, abc.Iterable))
f = Foo()
print(isinstance(f, abc.Iterable))
True
True
s = 'ABC'
for char in s:
print(char)
A
B
C
s = 'ABC'
it = iter(s)
while True:
try:
print(next(it))
except StopIteration:
del it
break
A
B
C
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence_v2:
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text)
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
return SentenceIterator(self.words)
class SentenceIterator:
def __init__(self, words):
self.words = words
self.index = 0
def __next__(self):
try:
word = self.words[self.index]
except IndexError:
raise StopIteration()
self.index += 1
return word
def __iter__(self):
return self
__iter__
实例化并返回一个迭代器
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence_v3:
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text)
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
for word in self.words:
yield word
return # 可有可无
yield
惰性求值
# yield
def gen_AB():
print('start')
yield 'A'
print('continue')
yield 'B'
print('end') # 第三次迭代到这里后, 抛出异常, 被 for 捕捉, 停止迭代
for c in gen_AB():
print('--> ', c)
start
--> A
continue
--> B
end
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence_v4:
def __init__(self, text):
self.text = text
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
for match in RE_WORD.finditer(self.text):
yield match.group()
惰性求值与迫切求值
l1 = [x for x in gen_AB()]
start
continue
end
for x in l1:
print(x)
A
B
g1 = (x for x in gen_AB())
for x in g1:
print(x)
start
A
continue
B
end
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence_v5:
def __init__(self, text):
self.text = text
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self): # 直接返回一个 iter
return (match.group() for match in RE_WORD.finditer(self.text))
无限等差数列
class ArithmeticProgression:
def __init__(self, begin, step, end=None):
self.begin, self.step, self.end = begin, step, end
def __iter__(self):
result = type(self.begin + self.step)(self.begin) 将
forever = self.end is None
index = 0
while forever or result < self.end:
yield result
index += 1
result = self.begin + self.step * index
def aritprog_gen(begin, step, end=None):
result = type(begin + step)(begin)
forever = end is None
index = 0
while forever or result < end:
yield result
index += 1
result = begin + step * index
itertools 中的 等差数列
import itertools
gen = itertools.count(1, .5)
print(next(gen))
print(next(gen))
print(next(gen))
1
1.5
2.0
itertools.takewhile
生成一个使用另一个生成器的生成器, 仅在计算结果为 False 时停止
gen2 = itertools.takewhile(lambda n: n < 3, itertools.count(1, .5))
print(list(gen2))
[1, 1.5, 2.0, 2.5]
def aritprog_gen2(begin, step, end=None):
first = type(begin + step)(begin)
ap_gen = itertools.count(first, step)
if end is not None:
ap_gen = itertools.takewhile(lambda n: n < end, ap_gen)
return ap_gen
标准库中的生成器
用于过滤的生成器函数
from itertools import filterfalse, dropwhile, takewhile, compress, islice
def vowel(c):
return c.lower() in 'aeiou'
print('filter: ', list(filter(vowel, 'Aardvark'))) # 产出所有 aeiou
print('filterfalse: ', list(filterfalse(vowel, 'Aardvark'))) # 产出所有 除了aeiou
print('dropwhile: ', list(dropwhile(vowel, 'Aardvark'))) # 从第一个不是 aeiou 的元素开始产出到末尾
print('takewhile: ', list(takewhile(vowel, 'Aardvark'))) # 从第一个元素开始产出 到不是 aeiou 的元素停止
print('compress: ', list(compress('Aardvark', (1, 0, 1, 1, 0, 1)))) # 产出 后面 it 为真的元素
print('islice: ', list(islice('Aardvark', 1, 7, 2))) # 类似于切片
filter: ['A', 'a', 'a']
filterfalse: ['r', 'd', 'v', 'r', 'k']
dropwhile: ['r', 'd', 'v', 'a', 'r', 'k']
takewhile: ['A', 'a']
compress: ['A', 'r', 'd', 'a']
islice: ['a', 'd', 'a']
用于映射的生成器函数
from itertools import accumulate, starmap
from operator import mul
sample = [5, 4, 2, 8, 7, 6, 3, 0, 9, 1]
print('accumulate sum(default): ', list(accumulate(sample)))
print('accumulate min: ', list(accumulate(sample, min)))
print('accumulate max: ', list(accumulate(sample, max)))
print('accumulate mul: ', list(accumulate(sample, mul)))
print('accumulate fact: ', list(accumulate(range(1, 11), mul)))
accumulate sum(default): [5, 9, 11, 19, 26, 32, 35, 35, 44, 45]
accumulate min: [5, 4, 2, 2, 2, 2, 2, 0, 0, 0]
accumulate max: [5, 5, 5, 8, 8, 8, 8, 8, 9, 9]
accumulate mul: [5, 20, 40, 320, 2240, 13440, 40320, 0, 0, 0]
accumulate fact: [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
print('enumerate: ', list(enumerate('Ryugu Reina', 1)))
print('map', list(map(mul, range(11), range(11))))
print('map', list(map(mul, range(11), range(3)))) # 取最小长度
print('starmap', list(starmap(mul, enumerate('Ryugu Reina', 1))))
print('starmap', list(starmap(lambda a, b: b / a, enumerate(accumulate(sample), 1))))
enumerate: [(1, 'R'), (2, 'y'), (3, 'u'), (4, 'g'), (5, 'u'), (6, ' '), (7, 'R'), (8, 'e'), (9, 'i'), (10, 'n'), (11, 'a')]
map [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
map [0, 1, 4]
starmap ['R', 'yy', 'uuu', 'gggg', 'uuuuu', ' ', 'RRRRRRR', 'eeeeeeee', 'iiiiiiiii', 'nnnnnnnnnn', 'aaaaaaaaaaa']
starmap [5.0, 4.5, 3.6666666666666665, 4.75, 5.2, 5.333333333333333, 5.0, 4.375, 4.888888888888889, 4.5]
合并多个可迭代对象的生成器
from itertools import chain, zip_longest, product
print('chain: ', list(chain('abc', range(2))))
print('chain.from_iterable:', list(chain.from_iterable(enumerate('abc'))))
print('zip: ', list(zip('abc', range(10))))
print('zip_longest: ', list(zip_longest('abc', range(10), fillvalue='q')))
chain: ['a', 'b', 'c', 0, 1]
chain.from_iterable: [0, 'a', 1, 'b', 2, 'c']
zip: [('a', 0), ('b', 1), ('c', 2)]
zip_longest: [('a', 0), ('b', 1), ('c', 2), ('q', 3), ('q', 4), ('q', 5), ('q', 6), ('q', 7), ('q', 8), ('q', 9)]
print('product', list(product('ABC', range(2))))
suits = 'spades hearts diamonds clubs'.split()
print('product', list(product('AK', suits)))
print('product', list(product('ABC')))
print('product', list(product('AB', repeat=3))) #<==> ('AB', 'AB', 'AB')
product [('A', 0), ('A', 1), ('B', 0), ('B', 1), ('C', 0), ('C', 1)]
product [('A', 'spades'), ('A', 'hearts'), ('A', 'diamonds'), ('A', 'clubs'), ('K', 'spades'), ('K', 'hearts'), ('K', 'diamonds'), ('K', 'clubs')]
product [('A',), ('B',), ('C',)]
product [('A', 'A', 'A'), ('A', 'A', 'B'), ('A', 'B', 'A'), ('A', 'B', 'B'), ('B', 'A', 'A'), ('B', 'A', 'B'), ('B', 'B', 'A'), ('B', 'B', 'B')]
把输入的各个元素扩展成多个输出元素的生成器
from itertools import count, cycle, repeat, combinations, combinations_with_replacement, permutations, islice
ct = count()
print('count: ', next(ct), next(ct), next(ct))
print('count & islice: ', list(islice(count(1, .3), 3)))
cy = cycle('RUA')
print('cycle: ', next(cy), next(cy), next(cy), next(cy), next(cy), next(cy))
rp = repeat(6)
print('repeat: ', next(rp), next(rp), next(rp))
print('repeat: ', list(repeat(8, 4)))
print('repeat: ', list(map(mul, range(11), repeat(5))))
print('combinations', list(combinations('ABC', 2)))
print('combinations', list(combinations_with_replacement('ABC', 2)))
print('combinations', list(combinations('ABC', 1)))
print('permutations', list(permutations('ABC', 2)))
count: 0 1 2
count & islice: [1, 1.3, 1.6]
cycle: R U A R U A
repeat: 6 6 6
repeat: [8, 8, 8, 8]
repeat: [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
combinations [('A', 'B'), ('A', 'C'), ('B', 'C')]
combinations [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
combinations [('A',), ('B',), ('C',)]
permutations [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
用于重新排列的元素生成器
from itertools import groupby, tee
print(list(groupby('LLLLLLLAAAAAAGGGGGGGGGGGGGGGGGGGGGGGGG')))
for key, group in groupby('LLLLLLLAAAAAAGGGGGGGGGGGGGGGGGGGGGGGGG'):
print(key, '-->', list(group))
print()
for key, group in groupby(['rua', 'aur', 'rau', 'aaaa', 'afeswr', 'sgse'], key=len): # 按长度分组, 最好先排个序 -_-|
print(key, '-->', list(group))
print()
for key, group in groupby(reversed(['rua', 'aur', 'rau', 'aaaa', 'afeswr', 'sgse']), key=len): # 从右向左迭代列表
print(key, '-->', list(group))
print()
g1, g2 = tee('ABC') # 产出多个相同的迭代器
print('tee', next(g1), next(g2), next(g1))
[('L', <itertools._grouper object at 0x000001E3B5D93760>), ('A', <itertools._grouper object at 0x000001E3B5D93A30>), ('G', <itertools._grouper object at 0x000001E3B5D91390>)]
L --> ['L', 'L', 'L', 'L', 'L', 'L', 'L']
A --> ['A', 'A', 'A', 'A', 'A', 'A']
G --> ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G']
3 --> ['rua', 'aur', 'rau']
4 --> ['aaaa']
6 --> ['afeswr']
4 --> ['sgse']
4 --> ['sgse']
6 --> ['afeswr']
4 --> ['aaaa']
3 --> ['rau', 'aur', 'rua']
tee A A B
yield from
def chain_(*iterables):
for it in iterables:
for i in it:
yield i
print(list(chain_('APPLE', range(3))))
['A', 'P', 'P', 'L', 'E', 0, 1, 2]
def chain_(*iterables):
for it in iterables:
yield from it
print(list(chain_('APPLE', range(3))))
['A', 'P', 'P', 'L', 'E', 0, 1, 2]
可迭代规约函数
iter 函数
python 在迭代对象时会调用 iter(x)
iter(v, w)
其中, w
是哨符, 当生成器产出这个对象时, 会抛出 StopIteration
, 停止迭代
from random import randint
def d6():
return randint(1, 6)
d6_iter = iter(d6, 1)
for roll in d6_iter: # 抛到 1 停止
print(roll, end=' ')
3 6 2 4
__EOF__
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数