Home > Article > Backend Development > How to use iterators and generators in Python
Those with built-in __iter__
methods are called iterable objects.
Python’s built-in str, list, tuple, dict, set, and file are all iterable objects.
x = 1.__iter__ # SyntaxError: invalid syntax # 以下都是可迭代的对象 name = 'nick'.__iter__ print(type(name)) # 'method-wrapper'>
Execute the __iter__
method of the iterable object, and the return value obtained is the iterator object.
Only strings and lists rely on index values, while other iterable objects cannot rely on index values and can only use iterator objects.
has a built-in __iter__
method, and executing this method will get the iterator itself.
Built-in __next__
method, executing this method will get a value in the iterator object.
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
Iterable objects can be traversed directly using regular for statements
The for loop is called an iterator loop, and must be iterable after 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()
After implementing the two methods __iter__() and __next__() in the class, you can use it as an iterator to use.
# The __iter__() method returns a special iterator object that implements the __next__() method and identifies the completion of the iteration through the StopIteration exception.
__next__() method returns the next iterator object.
StopIteration exception is used to identify the completion of iteration to prevent infinite loops. In the __next__() method, we can set the StopIteration exception to be triggered after completing the specified number of cycles to end the iteration. .
Create an iterator that returns a number. The initial value is 1, gradually increments by 1, and stops execution after 20 iterations:
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
In Python, the function that uses yield is called Generator.
A generator is a special function that returns an iterator and can only be used for iterative operations. In other words, a generator is an iterator.
During the process of calling the generator, each time it encounters yield, the function will pause and save all current running information, return the value of yield, and continue from the current position the next time the next() method is executed. run.
Call a generator function and return an iterator object.
yieldCan be followed by multiple values (can be of any type), but the returned value is of tuple type.
Provides a way to customize iterators
yield can pause the function and provide the current return value
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()
yield and return:
The same thing: both are used inside the function, both can return a value, and the return value has no type or number Restrictions
Differences: return can only return a value once; yield can return multiple values
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)}")
Complex version:
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
Replace [] in the list comprehension with () to get a generator expression Mode.
Advantages: Compared with list comprehensions, it can save memory and only generate one value in memory at a time
t = (i for i in range(10)) print(t) # <generator object at 0x00000000026907B0> print(next(t)) # 0 print(next(t)) # 1
Example:
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.
The above is the detailed content of How to use iterators and generators in Python. For more information, please follow other related articles on the PHP Chinese website!