Pythonイテレータとジェネレータ
「入場から実際の戦闘までのPython3」を参照
1つ、イテレータ
1.イテレータチームイメージの__iter()メソッドはイテレータを返し、このイテレータの__next()メソッドはイテレータオブジェクトの次の要素を返します。
注:イテレータはfor inで出力でき、イテレータは次の方法()
2.Pythonは、対応する2つの組み込み関数iter()とnext()を提供します。組み込み関数iter()は、反復可能なオブジェクトに作用します。オブジェクトの__iter __()メソッドを呼び出して、イテレーターを返します。 in function next())このイテレータに作用して、これによって呼び出された__next()__メソッドを呼び出して、反復可能な要素の次の要素を返します。
alist = [1,3,5,19,7]
it = iter(alist)#返回一个迭代器
print(type(alist))
print(type(it))
print(next(it))#得到迭代器的下一个值
运行结果如下:
<class 'list'>
<class 'list_iterator'>
1
次のクラスAは__iter __()メソッドを実装しているため、クラスAのオブジェクトはイテレータオブジェクトであり、iter()のメソッドはイテレータを返す必要があります。つまり、クラスBのオブジェクトはイテレータである必要があります。たとえば、クラスBは__next __()メソッドを実装する必要があります
import time
class A(object):
def __iter__(self):
return B()
class B(object):
def __next__(self):
return "hello"
iterable = A()#可迭代对象 可迭代对象由下列方法进行迭代
iterator = iter(iterable)#迭代器 迭代器用next方法
#一直打印hello
i = 0
for e in iterable:
print(e)
time.sleep(1)
print(i)
i += 1
运行结果如下:
hello
0
hello
1
hello
2
hello
3
hello
#需要自己按下停止按钮,这里没有设置什么时候停止,而是一个死循环
class A(object):
def __iter__(self):
return B()
class B(object):
def __init__(self):
self.i = 0
self.data = [2,4,8]
def __next__(self):
if self.i == 3:#计数,到3就停止执行
raise StopIteration()
self.i += 1
return self.data[self.i-1]#返回每个值
iterable = A()
for e in iterable:
print(e,end=" ")
运行结果如下:
2 4 8
3.一般に、イテレータオブジェクトのクラスとイテレータのクラスは、このように完全に分離されているわけではなく、同じクラスです。このクラスは、__ iter __()メソッドと__next __()メソッドを同時に実装するため、このタイプでもオブジェクトの反復可能オブジェクトはイテレータでもあります
class X(object):
def __init__(self):
self.i = 0
self.data = [2,4,8]
def __iter__(self):
return self
def __next__(self):
if self.i == 3:
raise StopIteration()
self.i += 1
return self.data[self.i-1]
b = X()
it = iter(b)#得到迭代器
print(next(it))
#print(next(it))
b2 = X()
for i in b2:
print(i)
运行结果如下:
2
2
4
8
4.オブジェクトは反復可能です。そのクラスは__iter __()メソッドを実装するだけでなく、そのクラスは__getitem __()メソッドも実装できます。
5. forループを使用して無限ループを出力する場合、2番目のパラメーターはキー(キーワード)です。このメソッドを実装するクラスオブジェクトobjの場合、obj [key]を介してキーに対応する値を取得できます。
class Y:
def __getitem__(self,i):
return i * i
y = Y()
print(y[2])
运行结果如下:
4
class MyDict:
def __init__(self):
self.dict = {
}
def __getitem__(self,key):
return self.dict[key]
def __setitem__(self,key,value):
self.dict[key] = value
def __len__(self):
return len(self.dict)
d = MyDict()
d['李萍'] = 67.5#调用setitem方法
print(d['李萍'])#调用getitem方法
d['王伟'] = 77.5
print(d['王伟'])
运行结果如下:
67.5
77.5
第二に、発電機
1.ジェネレーターは、イテレーターを作成するためのシンプルで強力なツールです。一連の値を生成できる関数でもあります。ジェネレーターは、最後に実行されたステートメントを記憶します。データが必要な場合は常に、ジェネレーターは中断時に続行から開始します。そして、yieldステートメントを介して新しいデータを生成します。したがって、ジェネレーターは特別なイテレーターであり、反復可能なオブジェクトです。
ジェネレーター機能
def gen(n):
for i in range(n):
yield(i)
'''生成器会记住函数执行的状态,当再次调用__next__()方法时,
会根据上次的位置和状态,继续执行,当再次遇到yield语句,
又产生一个新的返回值并终止当前的执行.
'''
g = gen(5)
print(g.__next__())
print(g.__next__())
print(next(g))#也可以用这种方法(因为生成器也是迭代器)
print(g)#g是一个生成器的对象
print(type(g))
#迭代
g = gen(10)#生成器是一个可迭代对象
for i in g:
print(i)
运行结果如下:
0
1
2
<generator object gen at 0x000002335EEF0A50>
<class 'generator'>
0
1
2
3
4
5
6
7
8
9
2. returnを含む関数は、関数の実行を停止し、returnステートメントに遭遇すると戻ります。関数の各実行は独立しており、最初から開始されます。前の実行の状態と位置は保存されません。
3. yieldを含むgenerator関数は、一連の値を生成するために使用されます。実行されるたびに、yieldステートメントは実行を停止し、yieldステートメントの結果を返しますが、前の実行の状態は内部的に保持されます。次の実行は前の実行から開始されます。実行されたyieldの後のコードは、yieldに再び遭遇して戻るまで、実行を続けます。
4.ジェネレーター関数を使用して一連の値を生成できます。これらの値はメモリに保存されませんが、必要に応じて生成されるため、多くのメモリを節約できます。
#求1到10的整数和
#生成器方法
def gen(n):
for i in range(n):
yield i
g = gen(11)#这是一个生成器
sum = 0
for e in g:
sum += e
print(sum)
运行结果:
55
#用生成器产生斐波拉西数列
def fib(M):
n,a,b = 0,0,1
while(n<M):
yield b
a,b = b,a+b#这个是同时完成a=b,b=a+b
n += 1
for x in fib(8):
print(x,end=" ")
运行结果如下:
1 1 2 3 5 8 13 21
3、標準ライブラリの反復ツール
1.zip関数。この関数の入力パラメーターは、任意の数の可変反復可能オブジェクトであり、データ要素(タプル反復子)を返します。各タプルは、複数の入力反復子の対応する要素で構成されます。
2.入力パラメーターがない場合、空のイテレーターが返されます
3.反復可能オブジェクトが入力された場合、データ要素(タプルのイテレーター)が返され、各タプルには1つの値しかありません。
4.複数の反復可能オブジェクトが入力された場合、データ要素(タプルのイテレーター)が返され、各タプルは入力された反復可能オブジェクトのオブジェクト要素で構成されます。
5. zipオブジェクトは反復可能なオブジェクトであるため、リストオブジェクトの作成には使用できますが、タプルオブジェクトの作成には使用できません。
result = zip()
print(list(result))
alist = [1,2,3]
result = zip(alist)
for e in result:
print(e,end=" ")
print()
str = ("许嵩","周杰伦","薛之谦")
result = zip(alist,str)
for e in result:
print(e)
运行结果如下:
[]
(1,) (2,) (3,)
(1, '许嵩')
(2, '周杰伦')
(3, '薛之谦')
a = [1,2,3]
b = ['a','b','c']
c = zip(a,b)#用zip将a,b打包
c = list(c)#要有这句话,否则报错
for i in c:
print(i)
d,e = zip(*c)#用zip将a,b解包
print(d,e)
运行结果如下:
(1, 'a')
(2, 'b')
(3, 'c')
(1, 2, 3) ('a', 'b', 'c')
6.関数は列挙し、反復可能なオブジェクトを入力し、列挙オブジェクトを返します。これは反復可能なオブジェクトでもあり、各要素は(index、value)の形式になっています。
7.関数chain()は、複数の反復可能オブジェクトを直列に接続する反復可能オブジェクトを返します
import itertools#需要先导入这个模块
it1 = [1,2,3]
it2 = (2,3,4)
it = itertools.chain(it1,it2)
for e in it:
print(e)
运行结果如下:
'''
1
2
3
2
3
4
'''
8.関数count()この関数はイテレータを返し、イテレータは均一な数のシーケンスを生成します。シーケンスの開始値はstartであり、隣接する2つのシーケンスの差はstepです。このシーケンスは無限シーケンスです。
from itertools import count
for i in count(10):#start=10 默认step=1
if i > 20:
break
print(i)
'''
10
11
12
13
14
15
16
17
18
19
20
'''
9.関数islice()もitertoolsの関数であり、関数の形式は次のとおりです。
islice(iterable、stop)
islice(iterable、start、stop [、step])
この関数は、反復可能なオブジェクトからスライスオブジェクトを生成するために使用されます。ここで、stopはスライスの終了位置、startは開始位置、stepはステップサイズです。
from itertools import islice,count
#2即是步长
#count(10)是一个迭代器
for i in islice(count(10),5,10,2):#第五个开始,到第十个,step=2
print(i)
运行结果如下:
'''
15
17
19
'''
10.関数cycle()は反復可能オブジェクトに作用して、ループを繰り返す反復可能オブジェクトに値のイテレーターを生成します
from itertools import cycle
count = 0
for item in cycle('xyz'):
if count > 9:
break
print(item,end=" ")
count += 1
'''
x y z x y z x y z x
'''
11.#Function Repeatこの関数は、オブジェクトの値が繰り返される時間イテレータを生成するために使用されます。この関数と関数cycle()の違いは、関数cycle()が作用するのに対し、関数cycle()は値のあるオブジェクトオブジェクトにのみ作用することです。複数の値を持つ1つの反復可能なオブジェクト
from itertools import repeat
r = repeat(7,3)#重复一个对象 多少次
for i in r:
print(i)
'''
7
7
7
'''