Maison  >  Article  >  développement back-end  >  Comment utiliser les itérateurs et les générateurs en Python

Comment utiliser les itérateurs et les générateurs en Python

PHPz
PHPzavant
2023-05-22 12:13:21870parcourir

1. Itérateur (foreach)

1. Objets itérables

Ceux avec la méthode __iter__ intégrée sont appelés objets itérables. __iter__方法的都叫可迭代的对象。

Python内置str、list、tuple、dict、set、file都是可迭代对象。

x = 1.__iter__  # SyntaxError: invalid syntax

# 以下都是可迭代的对象
name = 'nick'.__iter__
print(type(name))  # 'method-wrapper'>

2、迭代器对象

执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象。

只有字符串和列表都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的,只能使用迭代器对象。

  • 内置有__iter__方法,执行该方法会拿到迭代器本身。

  • 内置__next__

    Les str, list, tuple, dict, set et file intégrés de Python sont tous des objets itérables.
  • 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
2. Objet itérateur

Exécutez la méthode __iter__ de l'objet itérable, et la valeur de retour obtenue est l'objet itérateur.

Seules les chaînes et les listes reposent sur des valeurs d'index, tandis que les autres objets itérables ne peuvent pas s'appuyer sur des valeurs d'index et ne peuvent utiliser que des objets itérateurs.

Il existe une méthode __iter__ intégrée, et l'exécution de cette méthode obtiendra l'itérateur lui-même.

Méthode __next__ intégrée, l'exécution de cette méthode obtiendra une valeur dans l'objet itérateur.
  • s = 'hello'
    iter_s = iter(s) # 创建迭代器对象
    print(type(iter_s))  #  iter_s为迭代器对象
    
    while True:
        try:
            print(next(iter_s)) # 输出迭代器的下一个元素
    
        except StopIteration:
            break
    # hello

    3. Les itérateurs ont deux méthodes de base : iter() et next().
  • #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()
  • 4. for boucle d'itérateur

    Les objets itérables peuvent être parcourus directement à l'aide d'instructions for régulières
  • La boucle for est appelée une boucle d'itérateur, et le in doit être un objet itérable.

    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)

    5. Implémentez les itérateurs (__next__ et __iter__)
Après avoir implémenté les méthodes __iter__() et __next__() dans la classe, vous pouvez l'utiliser comme itérateur. La méthode

__iter__() renvoie un objet itérateur spécial qui implémente la méthode __next__() et signale la fin de l'itération via l'exception StopIteration. La méthode

__next__() renvoie l'objet itérateur suivant.

L'exception StopIteration est utilisée pour marquer la fin de l'itération afin d'éviter les boucles infinies. Dans la méthode __next__(), nous pouvons définir l'exception StopIteration pour qu'elle soit déclenchée après avoir terminé le nombre de boucles spécifié pour terminer l'itération.

Créez un itérateur qui renvoie un nombre. La valeur initiale est 1, incrémente progressivement de 1 et arrête l'exécution après 20 itérations :

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

1, plage simulée

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, séquence de Fibonacci
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()

two , Générateur.
  • 1, rendement

    En Python, la fonction qui utilise le rendement est appelée un générateur.
  • Un générateur est une fonction spéciale qui renvoie un itérateur et ne peut être utilisée que pour des opérations itératives. En d’autres termes, un générateur est un itérateur.

    Dans le processus d'appel du générateur pour qu'il s'exécute, la fonction s'arrêtera à chaque fois qu'elle rencontrera un rendement et enregistrera toutes les informations d'exécution actuelles, renverra la valeur de rendement et continuera à s'exécuter à partir de la position actuelle la prochaine fois que la méthode next() sera exécutée. exécuté.
Appelez une fonction génératrice et renvoyez un objet itérateur.

    yield
  • peut être suivi de plusieurs valeurs (peut être de n'importe quel type), mais la valeur renvoyée est de type tuple.

  • Fournir un moyen de personnaliser les itérateurs

yield peut suspendre la fonction et fournir la valeur de retour actuelle

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)}")

yield et return :

La même chose : les deux sont dans Lorsqu'ils sont utilisés en interne dans un fonction, une valeur peut être renvoyée, et il n'y a pas de limite sur le type ou le nombre de valeurs de retour

La différence : return ne peut renvoyer une valeur qu'une seule fois ; rendement peut renvoyer plusieurs valeurs​​🎜🎜🎜🎜2 . Méthode range() personnalisée 🎜
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
🎜Version complexe : 🎜
t = (i for i in range(10))
print(t)  # <generator object  at 0x00000000026907B0>
print(next(t))  # 0
print(next(t))  # 1
🎜3. Expression génératrice (i.for .in)🎜🎜Remplacez [] dans la compréhension de la liste par () pour obtenir une expression génératrice. 🎜🎜Avantages : par rapport aux compréhensions de listes, il peut économiser de la mémoire et ne génère qu'une seule valeur en mémoire à la fois🎜
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.
🎜Exemple : 🎜rrreee

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer