L'important est que la compréhension de la liste crée une nouvelle liste. Le générateur crée un objet itérable qui "filtre" le matériel source à la volée lorsque vous consommez les bits.
Imaginez que vous ayez un fichier journal de 2 To appelé "énormefichier.txt" et que vous souhaitiez le contenu et la longueur de toutes les lignes commençant par le mot "ENTRY".
Vous essayez donc de commencer par écrire une liste de compréhension:
logfile = open("hugefile.txt","r")
entry_lines = [(line,len(line)) for line in logfile if line.startswith("ENTRY")]
Cela accélère le fichier entier, traite chaque ligne et stocke les lignes correspondantes dans votre tableau. Ce tableau peut donc contenir jusqu'à 2 To de contenu. C'est beaucoup de RAM, et ce n'est probablement pas pratique pour vos besoins.
Nous pouvons donc utiliser un générateur pour appliquer un "filtre" à notre contenu. Aucune donnée n'est réellement lue jusqu'à ce que nous commencions à répéter le résultat.
logfile = open("hugefile.txt","r")
entry_lines = ((line,len(line)) for line in logfile if line.startswith("ENTRY"))
Pas même une seule ligne n'a encore été lue dans notre fichier. En fait, disons que nous voulons filtrer notre résultat encore plus loin:
long_entries = ((line,length) for (line,length) in entry_lines if length > 80)
Rien n'a encore été lu, mais nous avons spécifié maintenant deux générateurs qui agiront sur nos données comme nous le souhaitons.
Permet d'écrire nos lignes filtrées dans un autre fichier:
outfile = open("filtered.txt","a")
for entry,length in long_entries:
outfile.write(entry)
Maintenant, nous lisons le fichier d'entrée. Comme notre for
boucle continue de demander des lignes supplémentaires, le long_entries
générateur demande des lignes au entry_lines
générateur, renvoyant uniquement celles dont la longueur est supérieure à 80 caractères. Et à son tour, le entry_lines
générateur demande des lignes (filtrées comme indiqué) à l' logfile
itérateur, qui à son tour lit le fichier.
Ainsi, au lieu de "pousser" les données vers votre fonction de sortie sous la forme d'une liste entièrement remplie, vous donnez à la fonction de sortie un moyen de "tirer" les données uniquement lorsque cela est nécessaire. C'est dans notre cas beaucoup plus efficace, mais pas aussi flexible. Les générateurs sont à sens unique, un passage; les données du fichier journal que nous avons lu sont immédiatement supprimées, nous ne pouvons donc pas revenir à une ligne précédente. D'un autre côté, nous n'avons pas à nous soucier de conserver les données une fois que nous en avons terminé.
[exp for x in iter]
être juste du sucrelist((exp for x in iter))
? ou y a-t-il une différence d'exécution?