


Explication détaillée du générateur Python dans un article
Cet article vous apporte des connaissances pertinentes sur python, qui introduit principalement les problèmes liés aux générateurs, y compris le concept de générateur, le processus d'exécution des générateurs, les méthodes de rendement et de générateur, etc., comme suit Jetons un coup d'œil, j'espère que sera utile à tout le monde.
Apprentissage recommandé : Tutoriel vidéo Python
Cet article vous apporte des connaissances pertinentes sur Python, qui présente principalement des problèmes liés aux générateurs, y compris le concept de générateurs et les fonctions des générateurs. Jetons un coup d'œil au processus d'exécution , méthodes de rendement et de génération, etc. J'espère que cela sera utile à tout le monde.
1. Concept de générateur
Generator (anglais : générateur) est une chose très fascinante et est souvent considérée comme une compétence de programmation avancée en Python. Cependant, je suis toujours heureux de discuter de ce sujet avec les lecteurs ici - même si vous êtes peut-être débutant - car je crois que le but de la lecture de ce tutoriel n'est pas de vous limiter au niveau débutant. Vous devez avoir un cœur indiscipliné - pour le faire. devenez un maître Python. Commençons donc par en apprendre davantage sur les générateurs.
Vous vous souvenez du « itérateur » dans la section précédente ? Les générateurs et les itérateurs ont une certaine relation d'origine. Le générateur doit être itérable. Il est vrai que ce n'est pas seulement un itérateur, mais à part ça, il n'a pas beaucoup d'autres utilisations, on peut donc le comprendre comme un itérateur personnalisé très pratique.
2. Générateur simple
>>> my_generator = (x*x for x in range(4))
Est-ce très similaire à la compréhension de liste ? Observez attentivement, ce n'est pas une liste. Si vous obtenez comme ceci, c'est une liste :
>>> my_list = [x*x for x in range(4)]
La différence entre les deux ci-dessus est [] ou () Bien que ce soit une petite différence, les résultats sont complètement différents.
>>> dir(my_generator) ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
Pour une observation plus facile, j'ai réorganisé les résultats ci-dessus. Avez-vous découvert les méthodes nécessaires __inter__() et next() dans les itérateurs, ce qui montre qu'il s'agit d'un itérateur. S'il s'agit d'un itérateur, vous pouvez utiliser une boucle for pour lire ses valeurs dans l'ordre
>>> for i in my_generator: ... print i ... 0 1 4 9 >>> for i in my_generator: ... print i ...
Lorsque vous le parcourez pour la première fois, vous lisez et imprimez les valeurs dans my_generator dans l'ordre. lorsque vous le relisez, vous constatez qu’il n’y a aucun résultat. Cette fonctionnalité est également celle des itérateurs.
Pour cette liste, c'est différent :
>>> for i in my_list: ... print i ... 0 1 4 9 >>> for i in my_list: ... print i ... 0 1 4 9
Se pourrait-il que le générateur remplace simplement [] dans l'analyse de la liste par () ? Il s'agit simplement d'une forme d'expression et d'utilisation des générateurs. Suite à la dénomination des compréhensions de liste
, elle peut être appelée « expression analytique du générateur » (ou : dérivation du générateur, expression du générateur).
Les expressions d'analyse du générateur ont de nombreuses utilisations et constituent un bon choix pour remplacer les listes à de nombreux endroits. Surtout lorsqu'il s'agit d'un grand nombre de valeurs, comme mentionné dans la section précédente, les listes occupent plus de mémoire. L'avantage des itérateurs (les générateurs sont des itérateurs) est qu'ils occupent moins de mémoire, il n'est donc pas nécessaire d'instancier le générateur (ou l'itérateur). ) Transformez-le en liste et utilisez-le directement pour montrer les avantages de l'itération. Par exemple :
>>> sum(i*i for i in range(10)) 285
Faites attention à l'opération sum() ci-dessus. Ne pensez pas qu'il manque des parenthèses, c'est juste écrit comme ceci. N'est-ce pas charmant ? Si la liste, vous devez :
>>> sum([i*i for i in range(10)]) 285
Le générateur obtenu par l'analyse du générateur est couvert de quelques détails du générateur, et les zones applicables sont limitées. Ensuite, nous analyserons les composants internes du générateur et acquerrons une compréhension plus approfondie de cet outil magique.
3. Définition et processus d'exécution
yield signifie "production, production" en chinois. En Python, il est utilisé comme mot-clé (vous ne pouvez pas l'utiliser dans les noms de variables, de fonctions et de classes
Ceci) est le symbole du générateur.
>>> def g(): ... yield 0 ... yield 1 ... yield 2 ... >>> g <function g at 0xb71f3b8c>
a créé une fonction très simple. La seule différence par rapport aux fonctions vues précédemment est l'utilisation de trois instructions de rendement. Effectuez ensuite les opérations suivantes :
>>> ge = g() >>> ge <generator object g at 0xb7200edc> >>> type(ge) <type 'generator'>
La valeur de retour de la fonction établie ci-dessus est un objet de type générateur.
>>> dir(ge) ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
J'ai vu __iter__() et next() ici, indiquant qu'il s'agit d'un itérateur. Dans ce cas, bien sûr vous pouvez :
>>> ge.next() 0 >>> ge.next() 1 >>> ge.next() 2 >>> ge.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
Comme vous pouvez le voir sur cet exemple simple, la valeur de retour de la fonction contenant le mot-clé rendement est un objet de type générateur, et cet objet générateur est un itérateur.
Nous appelons des fonctions contenant des générateurs d'instructions de rendement. Un générateur est un itérateur défini avec une syntaxe de fonction ordinaire. Comme le montre l'exemple ci-dessus, pendant le processus de définition de ce générateur (également un itérateur), __inter__() et next() ne sont pas écrits comme l'itérateur de la section précédente, tant que l'instruction rendement est utilisée. , la fonction ordinaire. Elle devient comme par magie un générateur et possède les caractéristiques fonctionnelles d'un itérateur. La fonction de l'instruction
yield est de renvoyer la valeur correspondante lorsqu'elle est appelée. Analysons en détail le processus en cours ci-dessus :
1. ge = g() : à l'exception du retour du générateur, il n'y a aucune opération et aucune valeur n'est renvoyée.
2. ge.next() : Ce n'est qu'à ce moment-là que le générateur commence à s'exécuter lorsqu'il rencontre la première instruction rendement, il renvoie la valeur et suspend l'exécution (certains l'appellent
).为挂起)。
3. ge.next() :从上次暂停的位置开始,继续向下执行,遇到 yield 语句,将值返回,又暂停。
4. gen.next() :重复上面的操作。
5. gene.next() :从上面的挂起位置开始,但是后面没有可执行的了,于是 next() 发出异常。
从上面的执行过程中,发现 yield 除了作为生成器的标志之外,还有一个功能就是返回值。那么它跟 return 这个返回值有什么区别呢?
4. yield
为了弄清楚 yield 和 return 的区别,我写了两个函数来掩饰:
>>> def r_return(n): ... print "You taked me." ... while n > 0: ... print "before return" ... return n ... n -= 1 ... print "after return" ... >>> rr = r_return(3) You taked me. before return >>> rr 3
从函数被调用的过程可以清晰看出, rr = r_return(3) ,函数体内的语句就开始执行了,遇到 return,将值返
回,然后就结束函数体内的执行。所以 return 后面的语句根本没有执行。这是 return 的特点
下面将 return 改为 yield:
>>> def y_yield(n): ... print "You taked me." ... while n > 0: ... print "before yield" ... yield n ... n -= 1 ... print "after yield" ... >>> yy = y_yield(3) #没有执行函数体内语句 >>> yy.next() #开始执行 You taked me. before yield 3 #遇到 yield,返回值,并暂停 >>> yy.next() #从上次暂停位置开始继续执行 after yield before yield 2 #又遇到 yield,返回值,并暂停 >>> yy.next() #重复上述过程 after yield before yield 1 >>> yy.next() after yield #没有满足条件的值,抛出异常 Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
结合注释和前面对执行过程的分析,读者一定能理解 yield 的特点了,也深知与 return 的区别了。
一般的函数,都是止于 return。作为生成器的函数,由于有了 yield,则会遇到它挂起,如果还有 return,遇到它就直接抛出 SoptIteration 异常而中止迭代。
#!/usr/bin/env Python # coding=utf-8 def fibs(max): """ 斐波那契数列的生成器 """ n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 if __name__ == "__main__": f = fibs(10) for i in f: print i ,
运行结果如下:
$ python 21501.py 1 1 2 3 5 8 13 21 34 55
用生成器方式实现的斐波那契数列是不是跟以前的有所不同了呢?大家可以将本教程中已经演示过的斐波那契数列实现方式做一下对比,体会各种方法的差异。
经过上面的各种例子,已经明确,一个函数中,只要包含了 yield 语句,它就是生成器,也是迭代器。这种方式显然比前面写迭代器的类要简便多了。但,并不意味着上节的就被抛弃。是生成器还是迭代器,都是根据具体的使用情景而定。
5. 生成器方法
在 python2.5 以后,生成器有了一个新特征,就是在开始运行后能够为生成器提供新的值。这就好似生成器
和“外界”之间进行数据交流。
>>> def repeater(n): ... while True: ... n = (yield n) ... >>> r = repeater(4) >>> r.next() 4 >>> r.send("hello") 'hello
当执行到 r.next() 的时候,生成器开始执行,在内部遇到了 yield n 挂起。注意在生成器函数中, n = (yield
n) 中的 yield n 是一个表达式,并将结果赋值给 n,虽然不严格要求它必须用圆括号包裹,但是一般情况都这
么做,请大家也追随这个习惯。
当执行 r.send("hello") 的时候,原来已经被挂起的生成器(函数)又被唤醒,开始执行 n = (yield n) ,也就是
讲 send() 方法发送的值返回。这就是在运行后能够为生成器提供值的含义。
如果接下来再执行 r.next() 会怎样?
>>> r.next()
什么也没有,其实就是返回了 None。按照前面的叙述,读者可以看到,这次执行 r.next() ,由于没有传入任何值,yield 返回的就只能是 None.
还要注意,send() 方法必须在生成器运行后并挂起才能使用,也就是 yield 至少被执行一次。如果不是这样:
>>> s = repeater(5) >>> s.send("how") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't send non-None value to a just-started generator
就报错了。但是,可将参数设为 None:
>>> s.send(None) 5
这是返回的是调用函数的时传入的值。
此外,还有两个方法:close() 和 throw()
• throw(type, value=None, traceback=None):用于在生成器内部(生成器的当前挂起处,或未启动时在定
义处)抛出一个异常(在 yield 表达式中)。
• close():调用时不用参数,用于关闭生成器。
推荐学习:python视频教程
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

PHP et Python ont leurs propres avantages et inconvénients, et le choix dépend des besoins du projet et des préférences personnelles. 1.Php convient au développement rapide et à la maintenance des applications Web à grande échelle. 2. Python domine le domaine de la science des données et de l'apprentissage automatique.

Activer l'accélération du GPU Pytorch sur le système CentOS nécessite l'installation de versions CUDA, CUDNN et GPU de Pytorch. Les étapes suivantes vous guideront tout au long du processus: CUDA et CUDNN Installation détermineront la compatibilité de la version CUDA: utilisez la commande NVIDIA-SMI pour afficher la version CUDA prise en charge par votre carte graphique NVIDIA. Par exemple, votre carte graphique MX450 peut prendre en charge CUDA11.1 ou plus. Téléchargez et installez Cudatoolkit: visitez le site officiel de Nvidiacudatoolkit et téléchargez et installez la version correspondante selon la version CUDA la plus élevée prise en charge par votre carte graphique. Installez la bibliothèque CUDNN:

Docker utilise les fonctionnalités du noyau Linux pour fournir un environnement de fonctionnement d'application efficace et isolé. Son principe de travail est le suivant: 1. Le miroir est utilisé comme modèle en lecture seule, qui contient tout ce dont vous avez besoin pour exécuter l'application; 2. Le Système de fichiers Union (UnionFS) empile plusieurs systèmes de fichiers, ne stockant que les différences, l'économie d'espace et l'accélération; 3. Le démon gère les miroirs et les conteneurs, et le client les utilise pour l'interaction; 4. Les espaces de noms et les CGROUP implémentent l'isolement des conteneurs et les limitations de ressources; 5. Modes de réseau multiples prennent en charge l'interconnexion du conteneur. Ce n'est qu'en comprenant ces concepts principaux que vous pouvez mieux utiliser Docker.

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

Minio Object Storage: Déploiement haute performance dans le système Centos System Minio est un système de stockage d'objets distribué haute performance développé sur la base du langage Go, compatible avec Amazons3. Il prend en charge une variété de langages clients, notamment Java, Python, JavaScript et GO. Cet article introduira brièvement l'installation et la compatibilité de Minio sur les systèmes CentOS. Compatibilité de la version CentOS Minio a été vérifiée sur plusieurs versions CentOS, y compris, mais sans s'y limiter: CentOS7.9: fournit un guide d'installation complet couvrant la configuration du cluster, la préparation de l'environnement, les paramètres de fichiers de configuration, le partitionnement du disque et la mini

La formation distribuée par Pytorch sur le système CentOS nécessite les étapes suivantes: Installation de Pytorch: La prémisse est que Python et PIP sont installés dans le système CentOS. Selon votre version CUDA, obtenez la commande d'installation appropriée sur le site officiel de Pytorch. Pour la formation du processeur uniquement, vous pouvez utiliser la commande suivante: pipinstalltorchtorchVisionTorChaudio Si vous avez besoin d'une prise en charge du GPU, assurez-vous que la version correspondante de CUDA et CUDNN est installée et utilise la version Pytorch correspondante pour l'installation. Configuration de l'environnement distribué: la formation distribuée nécessite généralement plusieurs machines ou des GPU multiples uniques. Lieu

Lors de l'installation de Pytorch sur le système CentOS, vous devez sélectionner soigneusement la version appropriée et considérer les facteurs clés suivants: 1. Compatibilité de l'environnement du système: Système d'exploitation: Il est recommandé d'utiliser CentOS7 ou plus. CUDA et CUDNN: La version Pytorch et la version CUDA sont étroitement liées. Par exemple, Pytorch1.9.0 nécessite CUDA11.1, tandis que Pytorch2.0.1 nécessite CUDA11.3. La version CUDNN doit également correspondre à la version CUDA. Avant de sélectionner la version Pytorch, assurez-vous de confirmer que des versions compatibles CUDA et CUDNN ont été installées. Version Python: branche officielle de Pytorch

CENTOS L'installation de Nginx nécessite de suivre les étapes suivantes: Installation de dépendances telles que les outils de développement, le devet PCRE et l'OpenSSL. Téléchargez le package de code source Nginx, dézippez-le et compilez-le et installez-le, et spécifiez le chemin d'installation AS / USR / LOCAL / NGINX. Créez des utilisateurs et des groupes d'utilisateurs de Nginx et définissez les autorisations. Modifiez le fichier de configuration nginx.conf et configurez le port d'écoute et le nom de domaine / adresse IP. Démarrez le service Nginx. Les erreurs communes doivent être prêtées à prêter attention, telles que les problèmes de dépendance, les conflits de port et les erreurs de fichiers de configuration. L'optimisation des performances doit être ajustée en fonction de la situation spécifique, comme l'activation du cache et l'ajustement du nombre de processus de travail.
