Home  >  Article  >  Backend Development  >  How to use iterators and generators in Python

How to use iterators and generators in Python

PHPz
PHPzforward
2023-05-22 12:13:21910browse

1. Iterator (foreach)

1. Iterable objects

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'>

2. Iterator object

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

3. Iterators have two basic methods: iter() and next().

s = 'hello'
iter_s = iter(s) # 创建迭代器对象
print(type(iter_s))  #  iter_s为迭代器对象

while True:
    try:
        print(next(iter_s)) # 输出迭代器的下一个元素

    except StopIteration:
        break
# hello

4. for iterator loop

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()

5. Implement iterators (__next__ and __iter__)

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)

1. Simulate range

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

2. Fibonacci sequence

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(&#39;%s &#39; % i, end=&#39;&#39;)

# 1 1 2 3 5 8 13 21 34 55 89

2. Generator

1. yield

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))  # &#39;generator&#39;>

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

2. Custom range() method

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 [&#39;start&#39;, &#39;step&#39;, &#39;stop&#39;]:
                raise (&#39;参数名错误&#39;)

            if k == &#39;start&#39;:
                start = v
            elif k == &#39;stop&#39;:
                stop = v
            elif k == &#39;step&#39;:
                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

3. Generator expression (i.for .in)

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(&#39;32.txt&#39;, &#39;r&#39;, encoding=&#39;utf8&#39;) as f:
    nums = [len(line) for line in f]  # 列表推导式相当于直接给你一筐蛋

print(max(nums))  # 2


with open(&#39;32.txt&#39;, &#39;r&#39;, encoding=&#39;utf8&#39;) 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!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete