ホームページ >バックエンド開発 >Python チュートリアル >Python でイテレータとジェネレータを使用する方法
組み込み __iter__
メソッドを持つものは反復可能オブジェクトと呼ばれます。
Python の組み込みの str、list、tuple、dict、set、file はすべて反復可能なオブジェクトです。
x = 1.__iter__ # SyntaxError: invalid syntax # 以下都是可迭代的对象 name = 'nick'.__iter__ print(type(name)) # 'method-wrapper'>
イテラブル オブジェクトの __iter__
メソッドを実行し、得られる戻り値がイテレータ オブジェクトです。
文字列とリストのみがインデックス値に依存しますが、他の反復可能オブジェクトはインデックス値に依存できず、反復子オブジェクトのみを使用できます。
には組み込みの __iter__
メソッドがあり、このメソッドを実行するとイテレータ自体が取得されます。
組み込みの __next__
メソッド。このメソッドを実行すると、反復子オブジェクトの値が取得されます。
s = 'hello' iter_s = s.__iter__() print(type(iter_s)) # 'str_iterator'> iter_s为迭代器对象 while True: try: print(iter_s.__next__()) except StopIteration: break #hello
s = 'hello' iter_s = iter(s) # 创建迭代器对象 print(type(iter_s)) # iter_s为迭代器对象 while True: try: print(next(iter_s)) # 输出迭代器的下一个元素 except StopIteration: break # hello
通常の for ステートメントを使用して反復可能なオブジェクトを直接調べることができます
for ループはイテレータ ループと呼ばれ、in Object の後に反復可能である必要があります。 。
#str name = 'nick' for x in name: print(x) #list for x in [None, 3, 4.5, "foo", lambda: "moo", object, object()]: print("{0} ({1})".format(x, type(x))) #dict d = { '1': 'tasty', '2': 'the best', '3 sprouts': 'evil', '4': 'pretty good' } for sKey in d: print("{0} are {1}".format(sKey, d[sKey])) #file f = open('32.txt', 'r', encoding='utf-8') for x in f: print(x) f.close()
2 つのメソッド __iter__() と __next__() をクラスに実装した後、それをイテレータとして使用できます。
# __iter__() メソッドは、__next__() メソッドを実装する特別な反復子オブジェクトを返し、StopIteration 例外を通じて反復の完了を識別します。
__next__() メソッドは、次の反復子オブジェクトを返します。
StopIteration 例外は、無限ループを防ぐために反復の完了を識別するために使用されます。__next__() メソッドでは、指定されたサイクル数が完了した後に StopIteration 例外がトリガーされるように設定できます。反復を終了します。
数値を返す反復子を作成します。初期値は 1 で、徐々に 1 ずつ増加し、20 回の反復後に実行を停止します:
class MyNumbers: def __iter__(self): self.a = 1 return self def __next__(self): if self.a <= 20: x = self.a self.a += 1 return x else: raise StopIteration myclass = MyNumbers() myiter = iter(myclass) for x in myiter: print(x)
class Range: def __init__(self, n, stop, step): self.n = n self.stop = stop self.step = step def __next__(self): if self.n >= self.stop: raise StopIteration x = self.n self.n += self.step return x def __iter__(self): return self for i in Range(1, 7, 3): print(i) #1 #4
class Fib: def __init__(self): self._a = 0 self._b = 1 def __iter__(self): return self def __next__(self): self._a, self._b = self._b, self._a + self._b return self._a f1 = Fib() for i in f1: if i > 100: break print('%s ' % i, end='') # 1 1 2 3 5 8 13 21 34 55 89
Pythonでは、yieldを使用する関数をジェネレーターと呼びます。
ジェネレーターはイテレータを返す特別な関数であり、反復操作にのみ使用できます。言い換えれば、ジェネレータはイテレータです。
ジェネレーターの呼び出しプロセス中、yield が発生するたびに、関数は一時停止して現在実行中の情報をすべて保存し、yield の値を返し、次回 next() で現在の位置から続行します。メソッドが実行されます。実行します。
ジェネレータ関数を呼び出してイテレータ オブジェクトを返します。
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 是一个生成器 print(type(f)) # 'generator'> while True: try: print(next(f), end=" ") except StopIteration: sys.exit()
def my_range(start, stop, step=1): while start < stop: yield start start += 1 g = my_range(0, 3) print(f"list(g): {list(g)}")複合バージョン:
def range(*args, **kwargs): if not kwargs: if len(args) == 1: count = 0 while count < args[0]: yield count count += 1 if len(args) == 2: start, stop = args while start < stop: yield start start += 1 if len(args) == 3: start, stop, step = args while start < stop: yield start start += step else: step = 1 if len(args) == 1: start = args[0] if len(args) == 2: start, stop = args for k, v in kwargs.items(): if k not in ['start', 'step', 'stop']: raise ('参数名错误') if k == 'start': start = v elif k == 'stop': stop = v elif k == 'step': step = v while start < stop: yield start start += step for i in range(3): print(i) # 0,1,2 for i in range(99, 101): print(i) # 99,100 for i in range(1, 10, 3): print(i) # 1,4,7 for i in range(1, step=2, stop=5): print(i) # 1,3 for i in range(1, 10, step=2): print(i) # 1,3,5,7,9
t = (i for i in range(10)) print(t) # <generator object at 0x00000000026907B0> print(next(t)) # 0 print(next(t)) # 1例:
with open('32.txt', 'r', encoding='utf8') as f: nums = [len(line) for line in f] # 列表推导式相当于直接给你一筐蛋 print(max(nums)) # 2 with open('32.txt', 'r', encoding='utf8') as f: nums = (len(line) for line in f) # 生成器表达式相当于给你一只老母鸡。 print(max(nums)) # ValueError: I/O operation on closed file.
以上がPython でイテレータとジェネレータを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。