イテレータ
反復は Python の最も強力な機能の 1 つであり、コレクションの要素にアクセスする方法です。
イテレータは、トラバースの位置を記憶するオブジェクトです。
Iterator オブジェクトは、コレクションの最初の要素からすべての要素にアクセスされるまでアクセスされます。イテレータは前方にのみ進むことができ、後方には進むことができません。
イテレータには、iter() と next() という 2 つの基本メソッドがあります。
文字列、リスト、またはタプル オブジェクトを使用してイテレータを作成できます。
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>
Iterator オブジェクトは、通常の for ステートメントを使用して走査できます。
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ") # 输出为1行
上記のプログラムを実行すると、出力結果は次のようになります。
1 2 3 4
next() 関数を使用することもできます。
import sys # 引入 sys 模块
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
while True:
try:
print (next(it), end=" ")
except StopIteration:
sys.exit()
上記のプログラムを実行すると、出力結果は次のようになります。
1 2 3 4
イテレータを作成する
クラスをイテレータとして使用するには、クラス内に2 つのメソッドiter () およびnext () を実装する必要があります。
オブジェクト指向プログラミング (後で説明します) をすでに理解している場合は、すべてのクラスにコンストラクターがあることをご存知でしょう。Python のコンストラクターはinit () で、オブジェクトの初期化時に実行されます。
iter () メソッドは、 next () メソッドを実装する特別な反復子オブジェクトを返し、StopIteration 例外を通じて反復の完了を識別します。
next () メソッド (Python 2 では next()) は、次の反復子オブジェクトを返します。
1 から始まり 1 ずつ増加する数値を返すイテレータを作成します。
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
- クラス: 同じプロパティとメソッドを持つオブジェクトのコレクションを記述するために使用されます。コレクション内のすべてのオブジェクトに共通のプロパティとメソッドを定義します。オブジェクトはクラスのインスタンスであり、これについては指向プログラミングで後述します。
- メソッド: クラスに定義された関数はdefキーワードで定義されます。
実行出力は次のとおりです。
1
2
3
4
5
反復の停止
StopIteration 例外は、無限ループを防ぐために反復の完了をマークするために使用されます。next () メソッドでは、反復を終了するために指定された数のループが完了した後に StopIteration 例外がトリガーされるように設定できます。
10 回の反復後に実行を停止します。
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 10:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
実行出力は次のとおりです。
1
2
3
4
5
6
7
8
9
10
ビルダー
Python では、yield を使用する関数をジェネレーターと呼びます。
yieldはジェネレーター関数を定義するために使用されるキーワードです。ジェネレーター関数は、すべての結果を一度に返すのではなく、反復プロセス中に徐々に値を生成する特別な関数です。
ジェネレーターは通常の関数とは異なり、反復子を返す関数であり、反復演算のみに使用できます。ジェネレーターは反復子であると理解すると理解しやすいでしょう。
yieldステートメントがジェネレーター関数で使用される場合、関数の実行は一時停止され、yieldに続く式が現在の反復の値として返されます。
その後、ジェネレーターのnext()メソッドを呼び出すたび、またはforループを使用して反復処理を行うたびに、関数は、 yieldステートメントが再び検出されるまで、最後に一時停止した場所から実行を継続します。このように、ジェネレーター関数は、すべての結果を一度に計算して返すことなく、徐々に値を生成できます。
ジェネレーター関数を呼び出すと、イテレーター オブジェクトが返されます。
以下に、ジェネレーター関数の使用法を示す簡単な例を示します。
def countdown(n):
while n > 0:
yield n
n -= 1
# 创建生成器对象
generator = countdown(5)
# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
print(next(generator)) # 输出: 4
print(next(generator)) # 输出: 3
# 使用 for 循环迭代生成器
for value in generator:
print(value) # 输出: 2 1
上記の例では、カウントダウン関数はジェネレーター関数です。yieldステートメントを使用して、n から 1 までの逆数を徐々に生成します。yieldステートメントが呼び出されるたびに、関数は現在の逆数値を返し、次の呼び出しで最後に一時停止した場所から実行を再開します。
ジェネレーター オブジェクトを作成し、next()関数またはforループを使用してジェネレーターを反復処理することにより、ジェネレーター関数によって生成された値をステップ実行できます。この例では、まずnext()関数を使用して最初の 3 つの逆数値を取得し、次にforループを使用して残りの 2 つの逆数値を取得します。
ジェネレーター関数の利点は、オンデマンドで値を生成できるため、一度に大量のデータを生成して大量のメモリを占有する必要がなくなることです。さらに、ジェネレーターは他の反復ツール (for ループなど) とシームレスに連携して、簡潔で効率的な反復方法を提供できます。
上記のプログラムを実行すると、出力結果は次のようになります。
5
4
3
2
1
次の例では、yield を使用してフィボナッチ数列を実装します。
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
上記のプログラムを実行すると、出力結果は次のようになります。
0 1 1 2 3 5 8 13 21 34 55
**補足:** 黄金分割数列としても知られるフィボナッチ数列は、数学者レオナルド フィボナッチによってウサギの生殖を例として紹介されたため、「ウサギ数列」とも呼ばれます: 1、1、 2、3、5、8、13、21、34、... このシーケンスは 3 番目の項目から始まり、各項目は前の 2 つの項目の合計に等しくなります。