اضافه شدن آرگمان strict در کلاس zip توی نسخه 3.10 پایتون:

با کاربرد zip آشنایی داریم ، برای مواقعی هست که میخواهیم به صورت پارالل روی چند iterable پیمایش یا iteration انجام بدیم:
lst1 = [1, 2, 3]
lst2 = [10, 20, 30]
lst3 = [100, 200, 300]
print(list(zip(lst1, lst2, lst3)))
خروجی :
[(1, 10, 100), (2, 20, 200), (3, 30, 300)]

ولی zip به این صورت کار میکنه که وقتی یه iterable ای آیتم های کمتری داشته باشه نسبت به بقیه، عمل پیمایش بعد از تموم شدن آیتم های کوتاه ترین iterable تموم میشه:
lst1 = [1, 2]
lst2 = [10, 20, 30]
lst3 = [100, 200, 300]
print(list(zip(lst1, lst2, lst3)))
خروجی :
[(1, 10, 100), (2, 20, 200)]

گاهی ما دقیقا این رفتار رو میخوایم، گاهی بر عکسش رو، یعنی دوست داریم تا iteration تا آخرین عضو اون iterable ای که بیشترین آیتم رو داره ادامه داشته باشه، میومدیم از zip_longest استفاده میکردیم و برای اون iterable هایی که آیتم های کمتری دارن مقدار دیفالت در نظر میگرفتیم:
from itertools import zip_longest
lst1 = [1, 2]
lst2 = [10]
lst3 = [100, 200, 300]
print(list(zip_longest(lst1, lst2, lst3, fillvalue=None)))

خروجی :
[(1, 10, 100), (2, None, 200), (None, None, 300)]

حالا حالت سوم، فرض کنید iterable های ما از جای دیگه پر میشن و میان و ما از قبل نمیدونیم که کدوم چند تا عضو داره، ولی هدفمون اینکه باید فقط زمانی تابع ما خروجی بده که طول iterable هایی که پاس داده شدن برابر باشه، یعنی ما نه میخواهیم که آیتم ای نادیده گرفته بشه مثل حالت اول، نه با مقدار دیفالتی پر بشه...

چند تا راه حل وجود داره برای این کار، مثلا اولیش اینکه اگه لیست باشن اول len اون ها رو چک کنیم اگه برابر بودن ادامه بدیم اگه نبودن exception ای رو raise کنیم... که خب اگه iterable ما sequence type نباشه len رو ساپورت نمیکنه. راه دوم اینکه از iterator های اون استفاده کنیم. ولی الان خیلی راحت میتونیم با آرگمان strict این رو کنترل کنیم:
lst1 = [1, 2]
lst2 = [10]
lst3 = [100, 200, 300]
print(list(zip(lst1, lst2, lst3, strict=True)))

خروجی :
ValueError: zip() argument 2 is shorter than argument 1

@raspberry_python

Comments

Be the first to add a comment