迭代对象,迭代器,生成器

容器

容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用 in , not in 关键字判断元素是否包含在容器中

assert 如果为Fasle, 那么raise一个AssertionError

1
2
3
assert False, 'error'
assert True, 'error'
assert 1 in [1, 2, 3, 4],'error'

大多数容器提供了某种方式来获取其中每一个元素,(是可迭代对象赋予了容器这种能力)

可迭代对象 (iterable)

凡是可以返回一个迭代器的对象都可以称之为可迭代对象

可迭代对象实现了 iter (返回可迭代对象本身) 和 next 方法,

1
2
3
4
5
6
7
8
9
10
11
12
x = [1, 2, 3]  # 列表,可迭代对象
y = iter(x)
z = iter(x) # 两个不同的迭代器
next(y)
next(y)
next(z)
type(x) # list 可迭代对象
type(y) # list_iterator 具体的迭代类型

a = 'hahaha'
b = iter(a)
type(b) # str_iterator

迭代器 (iterator)

迭代器是一个带状态的对象,能在调用 next() 方法时返回容器的下一个值.

迭代器等有人需要的时候才生成值返回, 没调用的时候, 就处于休眠状态等待下一次调用。

生成器(generator)

相比其他容器对象,它更能节省内存和cpu。

1
2
sum(i for i in range(100_000_000)) # 生成器
sum[i for i in range(100_000_000)] # 列表推导式

生成器是一种特殊的迭代器,只需要yield关键字。生成器一定是迭代器(反之不成立)。

1
2
3
4
5
def someting():
result = []
for x in ..:
result.append(x)
return result

都可以改写

1
2
3
def iter_something():
for x in ..:
yield x

生成器表达式(generator expression)

列表推导式的生成器版本,但他返回的是一个生成器对象,而不是列表对象

1
a = (x * x for x in range(10))

生成器只能遍历一次

判断 a 是不是 b 的子序列

1
2
3
4
5
6
def is_subsequence(a, b):
b = iter(b)
return all(i in b for i in a)

print(is_subsequence([1, 3, 5], [1, 2, 3, 4, 5])) # True
print(is_subsequence([1, 4, 3], [1, 2, 3, 4, 5])) # False