zip() işlevi Python 2'de ortaya çıkmıştır (o zaman liste döndürüyordu), Python 3 ile birlikte tembel bir iteratör döndürmeye başladı. Birkaç diziyi eleman bazında tuple'lara "birleştirir", bu da paralel olarak yineleyen koleksiyonların işlenmesini kolay ve verimli hale getirdi.
Genellikle birkaç listeyi (veya başka tür dizileri) aynı anda işlemek gerekir; örneğin, anahtar-değer çiftleri üzerinden geçmek veya nokta-pair koordinatlarını işlemek. Gösterge senkronizasyonu yapmak, özellikle farklı uzunluktaki koleksiyonlar için hataların ve okunabilirliğin kaynağıdır.
zip() işlevi herhangi bir sayıda yineleyici nesneyi kabul eder ve her bir yineleyici nesneden karşılık gelen elemanları içeren tuple'lar döndüren bir iteratör sunar. Eğer diziler farklı uzunluktaysa, sonuç en kısa olanla sona erer.
names = ['Alice', 'Bob', 'Charlie'] ages = [24, 27, 30] for name, age in zip(names, ages): print(f'{name} {age} yaşında')
zip'i * ile açmak mümkündür:
pairs = [(1, 'a'), (2, 'b'), (3, 'c')] nums, chars = zip(*pairs) print(nums) # (1, 2, 3) print(chars) # ('a', 'b', 'c')
Farklı uzunluktaki koleksiyonları zip()'e verirsek ne olur?
zip() en kısa koleksiyonun sonuna ulaştığında durur — uzun koleksiyonların diğer elemanları göz ardı edilir.
print(list(zip([1,2,3], ['a','b']))) # [(1, 'a'), (2, 'b')]
Daha kısa dizileri varsayılan bir değer ile tamamlayarak tuple'lar almak mümkün mü?
Standart zip() bunu yapamaz, ancak bu tür bir davranış için itertools.zip_longest mevcuttur:
from itertools import zip_longest for a, b in zip_longest([1,2], ['x','y','z'], fillvalue=None): print(a, b) # 1 x # 2 y # None z
Zip() sonucunu "açarak" orijinal listeleri tekrar elde etmek mümkün mü?
Evet, eğer tüm orijinal koleksiyonlar aynı uzunluktaysa ve sonuç değiştirilmemişse, * operatörü ile zip'i açmak mümkündür.
pairs = [(1,2), (3,4)] a, b = zip(*pairs) print(a) # (1, 3) print(b) # (2, 4)
Farklı uzunluktaki ilişkili koleksiyonları zip'in özelliklerini göz önünde bulundurmadan işlemek:
lst1 = [1,2,3,4] lst2 = ['a','b'] for x, y in zip(lst1, lst2): print(x, y) # 1 a # 2 b # (3,4) ve lst1'den 'c', 'd' işlenmedi
Artılar:
Eksiler:
Bütün elemanların işlenmesini garanti altına almak için zip_longest'i fillvalue ile kullanmak:
from itertools import zip_longest lst1 = [1,2,3,4] lst2 = ['a','b'] for x, y in zip_longest(lst1, lst2, fillvalue='?'): print(x, y) # 1 a # 2 b # 3 ? # 4 ?
Artılar:
Eksiler: