Python --容器、迭代器、生成器
容器
可以理解为in、not in
想要判断str、list、tuple、set、dict是否在对应的str、list、tuple、set、dict ,后者就是容器,一般使用in、 not in进行判断。
容器可以自定义:
在类中定义 contains 方法就可以了
class A:
def __init__(self):
self.items = [1, 2]
def __contains__(self, item):
return item in self.items
a = A()
print(1 in a) # True
print(2 in a) # True
print(3 in a) # False
除了使用 in 判断元素是否在容器内之外,另外一个常用容器的功能是:输出容器内的所有元素。
例如执行 for x in [1, 2, 3],就可以迭代出容器内的所有元素。
迭代器
如果想使用 for 来迭代出数据,此时的语法就实现了迭代协议,这样的一个写法就是迭代器。
迭代器的实现:
在 Python 中,迭代器协议以下面2 个方法实现:
- iter_:这个方法返回对象本身,即 self
- next:这个方法每次返回迭代的值,在没有可迭代元素时,抛出 StopIteration 异常
注:迭代器只能迭代一次,再次迭代不会输出数据,’如果我们想每次执行都能迭代元素,只需每次迭代一个新对象即可。
可迭代对象:
凡是可以返回一个「迭代器」的对象,都可以称之为「可迭代对象」。
例子:
class A:
# A是迭代器 因为它实现了 __iter__ 和__next__方法
def __init__(self, n):
self.idx = 0
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.idx < self.n:
val = self.idx
self.idx += 1
return val
else:
raise StopIteration()
class B:
# B不是迭代器 但B的实例是一个可迭代对象
# 因为它只实现了 __iter__
# __iter__返回了A的实例 迭代细节交给了A
def __init__(self, n):
self.n = n
def __iter__(self):
return A(self.n)
# a是一个迭代器 同时也是一个可迭代对象
a = A(3)
for i in a:
print(i)
# <__main__.A object at 0x10eb95550>
print(iter(a))
# b不是迭代器 但它是可迭代对象 因为它把迭代细节交给了A
b = B(3)
for i in b:
print(i)
# <__main__.A object at 0x10eb95450>
print(iter(b))
生成器
「生成器」是一个特殊的「迭代器」,并且它也是一个「可迭代对象」。
有 2 种方式可以创建一个生成器:生成器表达式、生成器函数
# 创建一个生成器 类型是 generator
>>> g = (i for i in range(5))
>>> g
<generator object <genexpr> at 0x101334f50>
# 生成器就是一个迭代器
>>> iter(g)
<generator object <genexpr> at 0x101334f50>
# 生成器也是一个可迭代对象
>>> for i in g:
... print(i)
# 0 1 2 3 4