Önemli olan, liste kavrayışının yeni bir liste oluşturmasıdır. Jeneratör, bitleri tüketirken kaynak materyali anında "filtreleyecek" yinelenebilir bir nesne oluşturur.
"Hugefile.txt" adlı bir 2TB günlük dosyanız olduğunu ve "ENTRY" kelimesiyle başlayan tüm satırların içerik ve uzunluğunu istediğinizi düşünün.
Yani bir liste kavrayışı yazarak başlamayı deneyin:
logfile = open("hugefile.txt","r")
entry_lines = [(line,len(line)) for line in logfile if line.startswith("ENTRY")]
Bu, tüm dosyayı karıştırır, her satırı işler ve eşleşen satırları dizinizde saklar. Bu nedenle bu dizi en fazla 2 TB içerik içerebilir. Bu çok fazla RAM ve muhtemelen amaçlarınız için pratik değil.
Bunun yerine içeriğimize "filtre" uygulamak için bir jeneratör kullanabiliriz. Sonuç üzerinde yineleme yapmaya başlayana kadar hiçbir veri okunmaz.
logfile = open("hugefile.txt","r")
entry_lines = ((line,len(line)) for line in logfile if line.startswith("ENTRY"))
Dosyamızdan henüz tek bir satır okunmadı. Aslında, sonucumuzu daha da fazla filtrelemek istediğimizi düşünelim:
long_entries = ((line,length) for (line,length) in entry_lines if length > 80)
Hala hiçbir şey okunmadı, ancak şimdi verilerimize istediğimiz gibi davranacak iki jeneratör belirledik.
Filtrelenmiş satırlarımızı başka bir dosyaya yazalım:
outfile = open("filtered.txt","a")
for entry,length in long_entries:
outfile.write(entry)
Şimdi girdi dosyasını okuyoruz. Bizim gibi for
döngü ek satırlar talep devam ediyor long_entries
jeneratör gelen satırları talep entry_lines
uzunluğu 80 karakterden daha büyük olduğu sadece bu dönen, jeneratör. Ve sırayla, entry_lines
jeneratör logfile
yineleyiciden satırlar (belirtildiği gibi filtrelenir) ister ve bu da dosyayı okur.
Dolayısıyla, verileri çıktı işlevinize tam olarak doldurulmuş bir liste biçiminde "göndermek" yerine, çıktı işlevine verileri yalnızca gerektiğinde "çekmek" için bir yol sağlarsınız. Bu bizim durumumuzda çok daha verimli, ama o kadar esnek değil. Jeneratörler tek yönlü, tek geçişli; okuduğumuz günlük dosyasındaki veriler hemen atılır, bu nedenle önceki satıra geri dönemeyiz. Öte yandan, işimiz bittiğinde verileri saklamak konusunda endişelenmemiz gerekmiyor.
[exp for x in iter]
sadece şeker olabilirlist((exp for x in iter))
mi? ya da bir yürütme farkı var mı?