微信搜索关注「水滴与银弹」公众号,第一时间获取优质技术干货。7年资深后端研发,用简单的方式把技术讲清楚。
在 Python 开发中,我们经常听到有关「容器」、「迭代器」、「可迭代对象」、「生成器」的概念。
我们经常把这些概念搞混淆,它们之间有哪些联系和区别呢?
这篇文章,我们就来看一下它们之间的关系。
容器
首先,我们先来看一下容器是如何定义的?
简单来说,容器就是存储某些元素的统称,它最大的特性就是判断一个元素是否在这个容器内。
怎么理解这句话?
很简单,在 Python 中,我们通常使用 in
或 not in
来判断一个元素存在/不存在于一个容器内。
例如下面这个例子:
print('x' in 'xyz') # True
print('a' not in 'xyz') # True
print(1 in [1, 2, 3]) # True
print(2 not in (1, 2, 3)) # False
print('x' not in {
'a', 'b', 'c'}) # True
print('a' in {
'a': 1, 'b': 2}) # True
在这个例子中,我们可以看到 str
、list
、tuple
、set
、dict
都可以通过 in
或 not in
来判断一个元素是否在存在/不存在这个实例中,所以这些类型我们都可以称作「容器」。
那为什么这些「容器」可以使用 in
或 not in
来判断呢?
这是因为它们都实现了 __contains__
方法。
如果我们也想自定义一个容器,只需像下面这样,在类中定义 __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
在这个例子中,类 A
定义了 __contains__
方法,所以我们就可以使用 1 in a
的方式去判断这个元素是否在 A
这个容器内。
换句话说,一个类只要实现了 __contains__
方法,那么它就是一个「容器」。
我们在开发时,除了使用 in
判断元素是否在容器内之外,另外一个常用的功能是:输出容器内的所有元素。
例如执行 for x in [1, 2, 3]
,就可以迭代出容器内的所有元素。