itertools modülü, döngüleri daha kısa ve bellek dostu yazmanızı sağlayan yineleyici (iterator) araçları sunar: listeleri art arda bağlayan chain, veriyi sabit boyutlu parçalara bölen batched, ardışık çiftleri veren pairwise, ardışık aynı anahtarları gruplayan groupby, ara toplamları üreten accumulate, sonsuz akışları kesen islice ve kombinasyon üreten product, permutations, combinations. functools ise fonksiyonlarla çalışan araçları içerir: argümanları önceden sabitleyen partial, bir diziyi tek değere indiren reduce ve sonuçları önbelleğe alan cache ile lru_cache.

Bu yazıda her iki modülün en çok kullanılan araçlarını, belgelerin uyardığı tuzakları (özellikle groupby ile sıralama ilişkisi ve tükenen yineleyiciler), Python 3.13 ve 3.14'te eklenen batched(strict=True) ve Placeholder özelliklerini ve 3.15'teki comprehension içinde açma sözdizimiyle karşılaştırmayı göreceksiniz. Örnekler Python 3.15.2 ile çalıştırıldı. Yineleyici protokolünün kendisi generator ve iterator yazısında, sorted() için anahtar fonksiyonları ve operator modülü lambda, map, filter ve sorted yazısında anlatılıyor. Serinin tamamı için Python öğrenme rehberi sayfasına bakın.

Önce bir kavram: yineleyiciler tembeldir ve tükenir

Önce bir kavram: yineleyiciler tembeldir ve tükenir

itertools fonksiyonlarının tamamı bir yineleyici döndürür. Yineleyici değerleri ancak istendiğinde, birer birer üretir; bu yüzden milyonlarca öğelik bir akışı belleğe almadan işleyebilirsiniz. Bedeli şudur: bir yineleyici yalnızca bir kez gezilebilir. İlk gezinti bittiğinde boşalır ve ikinci gezinti hiçbir şey vermez, hata da vermez. Aşağıdaki örnekte sum() ikinci kez sıfır döndürdü; gerçek kodda bu tür sessiz hatalar uzun süre fark edilmeyebilir.

python
from itertools import islice

kare = (x * x for x in range(10))
print(list(islice(kare, 3)))
# çıktı: [0, 1, 4]
print(list(kare))
# çıktı: [9, 16, 25, 36, 49, 64, 81]
sayilar = iter([1, 2, 3])
print(sum(sayilar), sum(sayilar))
# çıktı: 6 0

islice() ilk üç değeri tükettiği için sonraki list() çağrısı kaldığı yerden devam etti. Aynı veriyi birden fazla kez gezmeniz gerekiyorsa en basit çözüm sonucu list() ile bir listeye almaktır. Bellek nedeniyle bu mümkün değilse tee() bir yineleyiciden birden fazla bağımsız yineleyici üretir; ancak belgeler bunun önemli miktarda yardımcı bellek gerektirebileceğini ve tee yineleyicilerinin iş parçacığı güvenli (threadsafe) olmadığını belirtir. Python 3.14 ile itertools yineleyicilerinin copy, deepcopy ve pickle desteği de kaldırıldı; 3.15.2'de copy.copy(itertools.count()) çağrısı TypeError: cannot pickle 'itertools.count' object verir.

Sonsuz yineleyiciler: count, cycle, repeat

Üç araç sonu olmayan akışlar üretir. count(start, step) sayarak ilerler, cycle() bir dizinin öğelerini sonsuza dek döndürür, repeat(nesne, n) aynı nesneyi n kez ya da n verilmezse sonsuza dek verir. Belgeler bu tür akışlara yalnızca onları kesen bir fonksiyon ya da döngüyle erişilmesi gerektiğini hatırlatır; list(count()) programınızı sonsuza dek çalıştırır. Kesmek için islice(), zip() (en kısa girdide durur) ya da break kullanılır.

python
from itertools import count, cycle, repeat, islice

print(list(islice(count(10, 5), 4)))
# çıktı: [10, 15, 20, 25]
print(list(islice(cycle("ABC"), 7)))
# çıktı: ['A', 'B', 'C', 'A', 'B', 'C', 'A']
print(list(repeat("x", 3)))
# çıktı: ['x', 'x', 'x']
for no, renk in zip(count(1), ["kırmızı", "yeşil"]):
    print(no, renk)
# çıktı: 1 kırmızı
# çıktı: 2 yeşil
print(list(map(pow, range(5), repeat(2))))
# çıktı: [0, 1, 4, 9, 16]

zip(count(1), liste) kalıbı yerleşik enumerate(liste, 1) ile aynı işi görür; numaralandırma için genellikle enumerate daha okunaklıdır. repeat() ise belgelerin gösterdiği gibi map() veya zip() içinde sabit bir argüman sağlamak için kullanışlıdır. Döngülerin genel kullanımı for ve while döngüleri yazısında anlatılıyor.

Birleştirme ve parçalama: chain, batched, pairwise, zip_longest

chain() birden fazla yinelenebilir nesneyi tek bir akış gibi art arda verir; elinizde bir liste listesi varsa chain.from_iterable() kullanılır. batched(veri, n) Python 3.12'de eklendi ve veriyi n uzunluğunda tuple'lara böler; son parça daha kısa olabilir. 3.13'te eklenen strict=True parametresi son parça eksikse ValueError fırlatır. Bu, verinin tam olarak çiftler ya da üçlüler hâlinde gelmesi gerektiği durumlarda hatayı erken yakalar. pairwise() ardışık örtüşen çiftleri verir ve iki ölçüm arasındaki farkları hesaplamak için idealdir. zip_longest() ise yerleşik zip() fonksiyonunun aksine en uzun girdiye kadar devam eder ve eksik yerleri fillvalue ile doldurur.

python
from itertools import chain, batched, pairwise, zip_longest

print(list(chain([1, 2], (3,), "ab")))
# çıktı: [1, 2, 3, 'a', 'b']
print(list(chain.from_iterable([[1, 2], [3], [4, 5]])))
# çıktı: [1, 2, 3, 4, 5]
print(list(batched("ABCDEFG", 3)))
# çıktı: [('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)]
try:
    list(batched("ABCDEFG", 3, strict=True))
except ValueError as e:
    print(e)
# çıktı: batched(): incomplete batch
print(list(pairwise([10, 13, 19, 20])))
# çıktı: [(10, 13), (13, 19), (19, 20)]
print([b - a for a, b in pairwise([10, 13, 19, 20])])
# çıktı: [3, 6, 1]
print(list(zip_longest("abc", [1], fillvalue="-")))
# çıktı: [('a', 1), ('b', '-'), ('c', '-')]

batched() özellikle toplu işlemler için kullanışlıdır: bir API'ye kayıtları yüzerli gruplar hâlinde göndermek ya da bir veritabanına binlerce satırı parça parça yazmak gibi. Belgelerin belirttiği gibi girdi tembel olarak, yalnızca bir parçayı dolduracak kadar okunur; bu yüzden çok büyük bir dosyayı bile satır satır gruplayabilirsiniz.

Python 3.15'te liste düzleştirmenin yeni bir yolu da geldi. PEP 798 ile comprehension'lar ve generator ifadeleri * ve ** ile açmayı destekliyor; What's New belgesi bu yazımı iç içe comprehension'lara ve itertools.chain() ile chain.from_iterable() kullanımına doğrudan bir alternatif olarak tanıtıyor. Kodunuz yalnızca 3.15 ve sonrasında çalışacaksa okunabilirliğe göre seçim yapabilirsiniz; eski sürümleri de destekliyorsanız chain.from_iterable() kullanmaya devam edin. Bu sözdiziminin ayrıntıları list comprehension yazısında.

python
from itertools import chain

listeler = [[1, 2], [3], [4, 5]]
print([*L for L in listeler])               # Python 3.15 ve sonrası
# çıktı: [1, 2, 3, 4, 5]
print(list(chain.from_iterable(listeler)))  # tüm sürümler
# çıktı: [1, 2, 3, 4, 5]

Filtreleme ve ara toplam: compress, takewhile, dropwhile, accumulate

compress(veri, seciciler) seçicinin doğru olduğu konumlardaki öğeleri verir. takewhile() koşul doğru olduğu sürece öğeleri alır ve koşul ilk kez yanlış olduğunda tamamen durur; dropwhile() ise tersini yapar: koşul doğru olduğu sürece öğeleri atlar, ilk yanlıştan sonra kalanların hepsini verir. Bu ikisinin filter() fonksiyonundan farkı önemlidir: filter() her öğeyi ayrı ayrı denetler, bu ikisi ise yalnızca baştaki kesintisiz diziye bakar. Aşağıdaki örnekte 3 sayısı 5'ten küçük olduğu hâlde takewhile sonucunda yer almadı, çünkü akış 6'da durmuştu.

accumulate() ara sonuçları üretir; varsayılan işlem toplamadır. İkinci argüman olarak iki argümanlı bir fonksiyon verirseniz o kullanılır: max ile o ana kadarki en büyük değeri, operator.mul ile birikimli çarpımı alırsınız. initial verilirse çıktı başlangıç değeriyle başlar ve girdiden bir öğe uzun olur.

python
from itertools import compress, takewhile, dropwhile, accumulate
import operator

print(list(compress(["Ali", "Ayşe", "Can"], [True, False, True])))
# çıktı: ['Ali', 'Can']
print(list(takewhile(lambda x: x < 5, [1, 4, 6, 3, 8])), list(dropwhile(lambda x: x < 5, [1, 4, 6, 3, 8])))
# çıktı: [1, 4] [6, 3, 8]
print(list(accumulate([100, -30, 45, -10])))
# çıktı: [100, 70, 115, 105]
print(list(accumulate([3, 1, 4, 1, 5], max)))
# çıktı: [3, 3, 4, 4, 5]
print(list(accumulate([1, 2, 3, 4], operator.mul, initial=10)))
# çıktı: [10, 10, 20, 60, 240]

İlk accumulate örneği bir hesabın hareketlerinden bakiye geçmişini çıkarıyor: 100 yatırıldı, 30 çekildi, 45 yatırıldı, 10 çekildi. Son bakiyeyi tek değer olarak isterseniz sum() yeterlidir; tüm ara adımlar gerekiyorsa accumulate doğru araçtır.

groupby: SQL GROUP BY değildir

groupby(veri, key) ardışık öğeleri anahtar fonksiyonunun değerine göre gruplar ve (anahtar, grup) çiftleri üretir. Belgeler davranışı Unix'teki uniq filtresine benzetir: anahtar her değiştiğinde yeni bir grup başlar. Bu yüzden SQL'in GROUP BY ifadesinden farklıdır; SQL sıradan bağımsız olarak aynı değerleri toplar. Verinin genellikle aynı anahtar fonksiyonuyla önceden sıralanmış olması gerekir. Sıralanmamış veride aynı şehir birden fazla grupta görünür.

python
from itertools import groupby

satislar = [("İzmir", 120), ("Ankara", 80), ("İzmir", 40), ("Ankara", 60), ("Bursa", 30)]
for sehir, grup in groupby(satislar, key=lambda s: s[0]):
    print(sehir, [t for _, t in grup])
# çıktı: İzmir [120]
# çıktı: Ankara [80]
# çıktı: İzmir [40]
# çıktı: Ankara [60]
# çıktı: Bursa [30]
sirali = sorted(satislar, key=lambda s: s[0])
for sehir, grup in groupby(sirali, key=lambda s: s[0]):
    print(sehir, sum(t for _, t in grup))
# çıktı: Ankara 140
# çıktı: Bursa 30
# çıktı: İzmir 160
gruplar = groupby(sirali, key=lambda s: s[0])
saklanan = [(k, g) for k, g in gruplar]
print([(k, list(g)) for k, g in saklanan])
# çıktı: [('Ankara', []), ('Bursa', []), ('İzmir', [])]
print([(k, len(list(g))) for k, g in groupby("aaabccaa")])
# çıktı: [('a', 3), ('b', 1), ('c', 2), ('a', 2)]

Üçüncü örnek belgelerin özellikle uyardığı ikinci tuzağı gösteriyor. Her grup, alttaki veriyi groupby nesnesiyle paylaşan bir yineleyicidir. groupby bir sonraki gruba geçtiğinde önceki grup artık görünmez olur. Grupları önce bir listeye toplayıp sonra okumaya çalıştığınızda hepsi boş geldi. Doğrusu, her grubu döngü içinde hemen tüketmek ya da belgelerdeki gibi list(g) ile saklamaktır. Son satır ise ardışıklık kuralını özetliyor: “aaabccaa” metninde iki ayrı “a” grubu var. Ayrıca sıralı sonuçta İzmir'in en sona düştüğüne dikkat edin; varsayılan sıralama karakter kodlarına göre yapıldığı için İ harfi Latin alfabesinin sonuna gelir.

Kombinasyon üreteçleri: product, permutations, combinations

Kombinasyon üreteçleri: product, permutations, combinations: product(repeat=2), permutations, combinations, combinations_with_replacement

Dört araç kombinatorik dizileri üretir. product() kartezyen çarpımdır ve iç içe for döngülerine eşdeğerdir; repeat ile aynı girdiyi kendisiyle çarparsınız. permutations(veri, r) sırası önemli olan, öğe tekrarı olmayan r uzunluğunda dizileri verir. combinations(veri, r) sırası önemsiz, tekrarsız seçimleri verir; combinations_with_replacement() ise aynı öğenin birden fazla kez seçilmesine izin verir. Belgelere göre combinations çıktıları girdinin sırasına göre sözlük sıralı (lexicographic) gelir.

python
from itertools import product, permutations, combinations, combinations_with_replacement

print(list(product("AB", [1, 2])))
# çıktı: [('A', 1), ('A', 2), ('B', 1), ('B', 2)]
print(len(list(product(range(10), repeat=4))))
# çıktı: 10000
print(["".join(p) for p in permutations("abc", 2)])
# çıktı: ['ab', 'ac', 'ba', 'bc', 'ca', 'cb']
print(list(combinations([1, 2, 3, 4], 2)))
# çıktı: [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
print(list(combinations_with_replacement("xy", 2)))
# çıktı: [('x', 'x'), ('x', 'y'), ('y', 'y')]
for beden, renk in product(["S", "M"], ["siyah", "beyaz"]):
    print(f"{beden}-{renk}")
# çıktı: S-siyah
# çıktı: S-beyaz
# çıktı: M-siyah
# çıktı: M-beyaz

Son örnek bir e-ticaret ürününün beden ve renk varyantlarını üretiyor; iç içe iki döngü yerine tek satır yeterli oldu. Bu araçlarla çalışırken sonuç sayısının ne kadar hızlı büyüdüğünü akılda tutun: dört haneli tüm sayısal şifreler 10 000 olasılık verdi; her hane veya öğe eklendiğinde sayı katlanarak artar. Sonucu list() ile belleğe almak yerine döngüyle işlemek bu yüzden önemlidir.

AraçSıra önemli miTekrar var mı"abc" için r=2 sonuç sayısı
product(repeat=2)evetevet9
permutationsevethayır6
combinationshayırhayır3
combinations_with_replacementhayırevet6

functools.partial ve Placeholder

partial(fonksiyon, *args, **kwargs), bazı argümanları önceden sabitlenmiş yeni bir çağrılabilir nesne döndürür. Belgelerin örneğinde partial(int, base=2) ikilik sistemde metin okuyan bir fonksiyon üretir. Çağrı sırasında verilen ek konumsal argümanlar sabitlenenlerin arkasına eklenir, anahtar kelime argümanları ise sabitlenenleri genişletir ya da ezer. Ortaya çıkan nesnenin func, args ve keywords öznitelikleri neyin sabitlendiğini gösterir.

Python 3.14'e kadar partial yalnızca baştaki konumsal argümanları sabitleyebiliyordu. 3.14'te eklenen functools.Placeholder nöbetçi nesnesi, yer tutucu bırakarak ortadaki ya da sondaki bir konumsal argümanı sabitlemenize izin verir. Çağrı sırasında yer tutucular önce doldurulur ve hepsinin doldurulması zorunludur. Aşağıdaki örnekte str.replace metodunun ilk iki argümanı boş bırakılıp üçüncüsü boş metne sabitlendi; sonuç verilen parçayı silen bir fonksiyon oldu. Placeholder anahtar kelime argümanı olarak verilemez.

python
from functools import partial, Placeholder

ikilik = partial(int, base=2)
print(ikilik("10010"))
# çıktı: 18
iki_hane = partial(round, ndigits=2)
print(iki_hane(19.98765))
# çıktı: 19.99
sil = partial(str.replace, Placeholder, Placeholder, "")
print(sil("Merhaba, sevgili sevgili dünya", " sevgili"))
# çıktı: Merhaba, dünya
print(ikilik.func, ikilik.args, ikilik.keywords)
# çıktı: <class 'int'> () {'base': 2}

partial özellikle geri çağırma (callback) bekleyen API'lerde işe yarar: bir fonksiyon tek argümanlı bir çağrılabilir bekliyorsa ve sizin fonksiyonunuz daha fazla argüman alıyorsa, fazlalıkları sabitleyerek uyumlu hâle getirirsiniz. Aynı işi bir lambda ile de yapabilirsiniz; partial nesnesinin avantajı, neyin sabitlendiğini özniteliklerinden okuyabilmenizdir.

functools.reduce

reduce(fonksiyon, dizi, initial) iki argümanlı bir fonksiyonu dizinin öğelerine soldan sağa birikimli olarak uygular ve tek bir değer döndürür: reduce(f, [1, 2, 3, 4, 5]), f(f(f(f(1, 2), 3), 4), 5) hesaplar. initial verilirse hesaplamanın başına konur ve dizi boşsa varsayılan sonuç olur. initial olmadan boş bir diziyle çağırmak TypeError verir; bu, boş olabilecek veriyle çalışırken sık rastlanan bir hatadır. Python 3.14'ten beri initial anahtar kelime argümanı olarak da verilebilir.

python
from functools import reduce
import operator

print(reduce(operator.add, [1, 2, 3, 4, 5]))
# çıktı: 15
print(reduce(lambda a, b: a * b, [], 1))
# çıktı: 1
print(reduce(lambda a, b: a * b, [7]))
# çıktı: 7
try:
    reduce(operator.add, [])
except TypeError as e:
    print(e)
# çıktı: reduce() of empty iterable with no initial value
print(reduce(operator.or_, [{"a": 1}, {"b": 2}, {"a": 3}], {}))
# çıktı: {'a': 3, 'b': 2}

Toplam için sum(), en büyük ve en küçük için max() ve min(), çarpım için math.prod() gibi yerleşik ya da hazır fonksiyonlar varken reduce kullanmak kodu gereksiz yere zorlaştırır. Functional Programming HOWTO da reduce ile yazılmış ifadelerin çoğu zaman bir for döngüsüyle daha anlaşılır yazılabileceğini belirtir. Ara değerlerin tamamını istiyorsanız belgeler itertools.accumulate() aracına yönlendirir.

cache ve lru_cache ile sonuçları önbelleğe almak

@cache bir fonksiyonun sonuçlarını argümanlarına göre saklar; aynı argümanlarla yapılan sonraki çağrılar hesaplama yapmadan saklanan değeri döndürür. Belgelere göre cache, lru_cache(maxsize=None) ile aynı sonucu verir; eski değerleri atması gerekmediği için boyut sınırlı lru_cache sürümünden daha küçük ve hızlıdır. Uzun süre çalışan süreçlerde, örneğin web sunucularında, bellek sınırsız büyümesin diye @lru_cache(maxsize=128) kullanılır: en son kullanılan 128 sonuç tutulur, en uzun süredir kullanılmayan atılır.

python
from functools import cache, lru_cache

@cache
def fib(n):
    return n if n < 2 else fib(n - 1) + fib(n - 2)

print(fib(80))
# çıktı: 23416728348467685
print(fib.cache_info())
# çıktı: CacheInfo(hits=78, misses=81, maxsize=None, currsize=81)

@lru_cache(maxsize=2)
def kare(x):
    print("hesaplanıyor:", x)
    return x * x

kare(2); kare(3); kare(2); kare(4); kare(3)
# çıktı: hesaplanıyor: 2
# çıktı: hesaplanıyor: 3
# çıktı: hesaplanıyor: 4
# çıktı: hesaplanıyor: 3
print(kare.cache_info())
# çıktı: CacheInfo(hits=1, misses=4, maxsize=2, currsize=2)
kare.cache_clear()
print(kare.cache_info())
# çıktı: CacheInfo(hits=0, misses=0, maxsize=2, currsize=0)
try:
    kare([1, 2])
except TypeError as e:
    print(e)
# çıktı: unhashable type: 'list' 

kare örneği LRU mantığını adım adım gösteriyor. Önbellekte iki yer var: 2 ve 3 hesaplandı, ardından 2 önbellekten geldi (tek isabet). 4 eklenince en uzun süredir kullanılmayan 3 atıldı, bu yüzden son çağrıda 3 yeniden hesaplandı. cache_info() isabet ve ıskaları, cache_clear() önbelleği temizlemeyi sağlar. Özgün fonksiyona __wrapped__ özniteliğiyle ulaşabilirsiniz.

Belgeler önbelleğin ne zaman kullanılmaması gerektiğini de açıkça yazar. Sonuçlar bir sözlükte tutulduğu için argümanlar hash'lenebilir olmalıdır; liste verdiğinizde yukarıdaki TypeError gelir. Yan etkisi olan fonksiyonları, her çağrıda yeni değiştirilebilir nesne üretmesi gereken fonksiyonları ve time() ya da random() gibi saf olmayan fonksiyonları önbelleğe almak anlamsızdır. f(a=1, b=2) ile f(b=2, a=1) farklı çağrılar sayılıp ayrı kayıt oluşturabilir. Bir metodu önbelleğe aldığınızda self de anahtarın parçası olur ve önbellek nesneye referans tuttuğu için nesne bellekten silinmeyebilir. Önbellek iş parçacığı güvenlidir, ama belgeler aynı argümanlı ikinci bir çağrının ilk çağrı bitmeden başlayabileceğini, yani fonksiyonun bir kez çalışma garantisi olmadığını belirtir.

cmp_to_key ve total_ordering

cmp_to_key(), iki argüman alıp negatif, sıfır ya da pozitif sayı döndüren eski tarz bir karşılaştırma fonksiyonunu, sorted(), min(), max() ve groupby() gibi araçların beklediği anahtar fonksiyonuna çevirir. Belgeler bunu öncelikle Python 2'den taşınan kodlar için bir geçiş aracı olarak tanımlar; yeni kodda çoğu sıralama bir anahtar fonksiyonuyla daha kolay ifade edilir. @total_ordering ise bir sınıfta __eq__ ile birlikte __lt__, __le__, __gt__ ya da __ge__ metotlarından birini tanımladığınızda geri kalan karşılaştırma metotlarını sizin için üretir.

python
from functools import cmp_to_key, total_ordering

def karsilastir(a, b):
    if len(a) != len(b):
        return len(a) - len(b)
    return (a > b) - (a < b)

print(sorted(["armut", "elma", "kivi", "ayva", "muz"], key=cmp_to_key(karsilastir)))
# çıktı: ['muz', 'ayva', 'elma', 'kivi', 'armut']

@total_ordering
class Surum:
    def __init__(self, ana, alt):
        self.t = (ana, alt)
    def __eq__(self, o):
        return self.t == o.t
    def __lt__(self, o):
        return self.t < o.t

print(Surum(3, 15) >= Surum(3, 14), Surum(3, 9) > Surum(3, 10))
# çıktı: True False

İlk sıralama önce uzunluğa, eşitlikte alfabeye göre yapıldı; aynı sonuç key=lambda s: (len(s), s) ile de alınır ve bu yazım daha kısadır. Surum sınıfı ise yalnızca iki metot tanımladığı hâlde >= ve > operatörlerini destekledi. Sürüm numaralarını metin olarak karşılaştırsaydınız “3.9” değeri “3.10” değerinden büyük çıkardı; tuple karşılaştırması bu hatayı önler. Belgeler total_ordering ile üretilen metotların daha yavaş çalıştığını ve hata izlerini karmaşıklaştırdığını, performansın önemli olduğu yerlerde altı karşılaştırma metodunu da elle yazmanın hızlandırabileceğini not eder. Özel metotların genel kullanımı dunder metotlar yazısında.

Hangi araç ne zaman?

Hangi araç ne zaman? Birden fazla listeyi art arda gezmek, Veriyi sabit boyutlu parçalara bölmek, Ardışık değer farkları, Ara toplamlar, bakiye geçmişi
İhtiyaçAraçNot
Birden fazla listeyi art arda gezmekchain, chain.from_iterable3.15 sonrası [*L for L in ...] da olur
Veriyi sabit boyutlu parçalara bölmekbatchedstrict=True ile eksik parçada hata (3.13)
Ardışık değer farklarıpairwiseÖrtüşen çiftler
Ara toplamlar, bakiye geçmişiaccumulateTek sonuç için sum()
Ardışık aynı değerleri gruplamakgroupbyÖnce aynı anahtarla sıralayın
Sonsuz akışı kesmekisliceDilimleme yineleyicilerde çalışmaz
Tüm varyantlarproductSonuç sayısı hızla büyür
Argüman sabitlemekpartial, PlaceholderPlaceholder 3.14
Pahalı ve saf fonksiyonu hızlandırmakcache, lru_cacheArgümanlar hash'lenebilir olmalı

Sık yapılan hatalar

  • Bir yineleyiciyi iki kez gezmeye çalışmak. İkinci gezinti sessizce boş döner; gerekiyorsa list() ile saklayın.
  • groupby öncesinde veriyi aynı anahtarla sıralamamak ve aynı grubun birden çok kez görünmesi.
  • groupby gruplarını sonradan okumak üzere saklamak. Bir sonraki gruba geçildiğinde öncekiler boşalır.
  • list(count()) ya da list(cycle(...)) gibi sonsuz akışları kesmeden tüketmek.
  • reduce fonksiyonunu boş diziyle initial olmadan çağırmak.
  • Liste ya da sözlük alan fonksiyonlara @cache uygulamak ve unhashable type hatası almak.
  • product ve permutations sonuçlarını büyük girdilerde list() ile belleğe almak.

Sık Sorulan Sorular

itertools fonksiyonları neden liste değil yineleyici döndürüyor?

Belgeler modülün hızlı ve bellek verimli araçlar sunmak için tasarlandığını belirtir. Yineleyiciler değerleri istendikçe ürettiği için büyük ya da sonsuz akışlarla çalışabilir. Liste gerekiyorsa sonucu list() ile sarmanız yeterlidir.

Bir listeyi n elemanlı parçalara nasıl bölerim?

Python 3.12 ve sonrasında itertools.batched(liste, n) kullanın. Son parçanın tam olmasını zorunlu tutmak istiyorsanız 3.13'ten beri strict=True verebilirsiniz.

lru_cache ile cache arasındaki fark nedir?

cache sınırsızdır ve lru_cache(maxsize=None) ile aynıdır. lru_cache varsayılan olarak 128 kayıt tutar ve sınır dolunca en uzun süredir kullanılmayanı atar. Uzun süre çalışan süreçlerde sınırlı önbellek bellek kullanımını kontrol altında tutar.

Liste listesini düzleştirmenin en iyi yolu hangisi?

Tüm sürümlerde çalışan yol list(chain.from_iterable(listeler)) ifadesidir. Yalnızca Python 3.15 ve sonrasını hedefliyorsanız PEP 798 ile gelen [*L for L in listeler] yazımı da aynı sonucu verir.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Python öğrenme rehberi · generator ve iterator · lambda, map, filter ve sorted · decorator yazma · list comprehension · collections modülü · for ve while döngüleri