# 1.1 容器Contain, 在Python中指的是使用类实现的一种数据结构,该类中一定要包含__contains__方法来兼容 # python的in关键字,来判断某个element是否在容器中。 class CustomContainer: def __init__(self) -> None: self.listdata = [10, 20, 30, 40, 50, 60, 70, 80, 90] def __contains__(self, element): if element in self.listdata: return True else: return False container1 = CustomContainer() print("Judge 10 in container1:") print(container1.__contains__(10)) print("Judge 50 in container1:") print(container1.__contains__(50)) print("Judge 100 in container1:") print(100 in container1) # 2.1 迭代器Iterator, 在Python中指用类实现的满足迭代器协议的数据结构, # 该类一定要包含__iter__和__next__方法 # 使得该迭代器能够被for关键字迭代. """ __iter__()方法返回一个迭代器对象,一般是self,这个返回的对象必须 实现了__next__()方法,因为for循环使用这个迭代器时,会首先调用 一次__iter__(),然后每次循环时调用这个__iter__()返回的对象 的__next__()方法,将__next__()返回值赋给循环变量。当数据结构 中的数据被遍历过一遍时,要__next__()负责抛出StopIteration异常, 告诉for语句停止迭代。另外,关于一个迭代器对象可以迭代几次的问题。 这个取决于抛出StopIteration异常前,是否有将这个迭代器对象的状态重置。 如果没有重置,第一次for循环不会出现问题,第二次不会报错, 但是for语句块没有循环。 """ class CustomIterator1: def __init__(self) -> None: self.listdata = [10,20,30,40,50,60,70, 80, 90] self.current_index = 0; def __iter__(self): return self def __next__(self): if self.current_index < len(self.listdata): self.current_index += 1 return self.listdata[self.current_index - 1] else: raise StopIteration() iterator1 = CustomIterator1() print('frist loop:') for idx, element in enumerate(iterator1): print('index:{}'.format(idx)) print(element) print('first loop end') print('second loop: ') for idx, element in enumerate(iterator1): print('index:{}'.format(idx + 1)) print(element) print('second loop end') # 2.2 循环后有重置的Iterator(在__next__()的raise StopIteration语句前进行处理 class CustomIterator2: def __init__(self) -> None: self.listdata2 = [110, 120, 130, 140, 150, 160, 170, 180, 190] self.current_index2 = 0 def __iter__(self): return self def __next__(self): if self.current_index2 < len(self.listdata2): self.current_index2 += 1 return self.listdata2[self.current_index2-1] else: # 对迭代器的索引值重置为0. self.current_index2 = 0 raise StopIteration() interator2 = CustomIterator2() print('frist loop:') for idx, element in enumerate(interator2): print('index:{}'.format(idx)) print(element) print('end loop:') print('second loop:') for idx, element in enumerate(interator2): print('index:{}'.format(idx)) print(element) print('end loop:')
运行结果:
Judge 10 in container1:
True
Judge 50 in container1:
True
Judge 100 in container1:
False
frist loop:
index:0
10
index:1
20
index:2
30
index:3
40
index:4
50
index:5
60
index:6
70
index:7
80
index:8
90
first loop end
second loop:
second loop end
frist loop:
index:0
110
index:1
120
index:2
130
index:3
140
index:4
150
index:5
160
index:6
170
index:7
180
index:8
190
end loop:
second loop:
index:0
110
index:1
120
index:2
130
index:3
140
index:4
150
index:5
160
index:6
170
index:7
180
index:8
190
end loop:
# 3.1 生成器Generator # 3.1.1 先了解yield,yield关键字:保留中间算法,下次继续执行, # 当调用next时,遇到yield就是暂停运行,并且返回yield后面的值 # 当再次调用next时,会从刚才暂停的地方继续运行,直到运行下一个yield """ def get_content(): print("start yield") yield 3 print("second yield") yield 4 print("thrid yield") yield 5 print("end") a = get_content() # print(dir(a)) print("****************") print(next(a)) print(next(a)) print("****************") result = next(a) print(result) print(next(a)) """ # 3.1.2 实现generator class CustomGenerator(): def __init__(self) -> None: self.current_data = 0 def __iter__(self): while self.current_data < 5: self.current_data += 1 yield self.current_data self.current_data = 0 generator1 = CustomGenerator() print("generator loop1:") for idx, element in enumerate(generator1): print('index:{}'.format(idx)) print(element) print("generator loop1 end") print("generator loop2:") for idx, element in enumerate(generator1): print('index:{}'.format(idx)) print(element) print("generator loop2 end")
运行结果:
generator loop1:
index:0
1
index:1
2
index:2
3
index:3
4
index:4
5
generator loop1 end
generator loop2:
index:0
1
index:1
2
index:2
3
index:3
4
index:4
5
generator loop2 end