FA-TOOLS — Header Component
آموزش itertools در پایتون — ابزارهای حرفه‌ای

آموزش itertools در پایتون — ابزارهای حرفه‌ای

سلام رفیق برنامه‌نویس! اگه دنبال اینی که کدهات رو تمیزتر، کارآمدتر و خفن‌تر بنویسی، یه جای درستی اومدی. ما تو دنیای پایتون ابزارهای زیادی داریم که زندگی رو آسون‌تر می‌کنن و itertools قطعاً یکی از ستاره‌های این زمینه است.

این مقاله یه سفر کامله به دنیای این ماژول قدرتمند که بهت یاد می‌ده چطوری با استفاده ازش، عملیات‌های پیچیده رو روی داده‌هات انجام بدی، بدون اینکه حافظه سیستمت رو پر کنی یا کدهای طولانی بنویسی. آماده‌ای تا به یه لول جدید از کدنویسی پا بذاری؟

ضمناً، اگه دنبال ابزارهای حرفه‌ای‌تر یا اسنیپت‌های پایتونی آماده می‌گردی که پروژه‌هات رو برق بندازه، حتماً یه سر به فروشگاه ابزارهای برنامه‌نویسی ما بزن. مطمئنم که چیزای باحالی پیدا می‌کنی! و اگه سوالی داشتی یا نیاز به راهنمایی بیشتر بود، مستقیم با این شماره تماس بگیر: 09202232789

🛣️ نقشه راه: ماژول itertools در یک نگاه

آموزش itertools در پایتون — ابزارهای حرفه‌ای — تصویر 1
╔════════════════════════════════════════════════════════════════════════════╗
║                   itertools: قدرت بی‌حد و حصر تکرارکننده‌ها                     ║
╠════════════════════════════════════════════════════════════════════════════╣
║ I. تکرارکننده‌های بی‌نهایت (Infinite Iterators)                               ║
║    •  count()     ➡️  تولید اعداد از یک شروع تا بی‌نهایت                      ║
║    •  cycle()     ➡️  تکرار بی‌نهایت یک دنباله                               ║
║    •  repeat()    ➡️  تکرار یک مقدار مشخص (N بار یا بی‌نهایت)               ║
╠════════════════════════════════════════════════════════════════════════════╣
║ II. تکرارکننده‌های ترکیبی (Combinatoric Iterators)                           ║
║    •  product()   ➡️  ترکیب کارتزین (Cartesian Product)                       ║
║    •  permutations() ➡️  جایگشت‌ها (بدون تکرار)                              ║
║    •  combinations() ➡️  ترکیبات (بدون تکرار)                                 ║
║    •  combinations_with_replacement() ➡️ ترکیبات (با تکرار)                  ║
╠════════════════════════════════════════════════════════════════════════════╣
║ III. تکرارکننده‌های کوتاه‌کننده (Terminating Iterators)                      ║
║    •  chain()     ➡️  ادغام چند تکرارکننده                                  ║
║    •  compress()  ➡️  فیلتر بر اساس یک انتخاب‌گر Boolean                     ║
║    •  groupby()   ➡️  گروه‌بندی عناصر متوالی یک دنباله                      ║
║    •  islice()    ➡️  برش زدن تکرارکننده‌ها                                 ║
║    •  takewhile() ➡️  گرفتن عناصر تا زمانی که شرطی برقرار است              ║
║    •  dropwhile() ➡️  رد کردن عناصر تا زمانی که شرطی برقرار است             ║
║    •  filterfalse() ➡️  فیلتر کردن عناصری که شرط را برآورده نمی‌کنند         ║
║    •  accumulate() ➡️  محاسبه تجمعی (مانند جمع یا ضرب)                     ║
║    •  tee()       ➡️  ساخت N کپی مستقل از یک تکرارکننده                     ║
╚════════════════════════════════════════════════════════════════════════════╝

itertools چیست و چرا باید از آن استفاده کنیم؟

آموزش itertools در پایتون — ابزارهای حرفه‌ای — تصویر 2

ماژول itertools در پایتون، یه گنجینه از توابع سریع و بهینه برای کار با تکرارکننده‌ها (iterators) است. این توابع بهت کمک می‌کنن تا عملیات‌های تکراری روی داده‌ها رو با حداقل مصرف حافظه و حداکثر سرعت انجام بدی. در واقع، فلسفه اصلی itertools اینه که داده‌ها رو “به صورت تنبل” (lazily) تولید می‌کنه. یعنی تا زمانی که به یک عنصر نیاز نداشته باشی، اون رو تولید نمی‌کنه و این باعث می‌شه برنامه‌هات خیلی کارآمدتر باشن، مخصوصاً وقتی با حجم زیاد داده سروکار داری.

تصور کن می‌خوای روی میلیون‌ها آیتم عملیاتی انجام بدی. اگه همه رو همون اول تو حافظه بارگذاری کنی، سیستم از نفس میفته. ولی با itertools، هر بار فقط یک آیتم رو پردازش می‌کنی و این یعنی مصرف حافظه ثابت و عملکرد عالی. این ماژول، برای هر برنامه‌نویسی که دنبال کدهای پایتونی بهینه و قدرتمنده، ضروریه.

تکرارکننده‌ها (Iterators) در برابر تکرارپذیرها (Iterables): یه نگاه سریع

قبل از اینکه شیرجه بزنیم تو توابع، خوبه که یه فرق کوچیک بین “تکرارپذیر” و “تکرارکننده” رو بدونیم. یه تکرارپذیر (Iterable) مثل لیست، تاپل یا رشته، چیزیه که می‌تونی روش حلقه بزنی. اما یه تکرارکننده (Iterator) شیئیه که وضعیت خودش رو نگه می‌داره و می‌تونه در هر لحظه، عنصر بعدی رو بهت بده (با متد next()). توابع itertools همگی تکرارکننده برمی‌گردونن.

دسته بندی توابع itertools: کار با بی‌نهایت و فراتر از آن

آموزش itertools در پایتون — ابزارهای حرفه‌ای — تصویر 3

توابع itertools رو می‌تونیم به چند دسته اصلی تقسیم کنیم که هر کدوم کاربردهای خاص خودشون رو دارن. بیا با هم تک تک‌شون رو بررسی کنیم.

۱. تکرارکننده‌های بی‌نهایت (Infinite Iterators)

این توابع، همونطور که از اسمشون پیداست، بی‌نهایت مقدار تولید می‌کنن. پس حواست باشه که باید با islice یا یه شرط دیگه محدودشون کنی وگرنه یه حلقه ابدی تشکیل می‌شه!

count(start=0, step=1)

مثل یه شمارنده عمل می‌کنه که از start شروع می‌شه و با گام step تا بی‌نهایت ادامه می‌ده. به درد تولید IDهای متوالی یا اندیس‌گذاری می‌خوره.


from itertools import count, islice

for i in islice(count(10, 2), 5):
    print(i)
# خروجی: 10, 12, 14, 16, 18
        

cycle(iterable)

عناصر یک تکرارپذیر رو به صورت نامحدود تکرار می‌کنه. عالیه برای کارهایی مثل تخصیص رنگ‌های متناوب یا نوبت‌بندی.


from itertools import cycle, islice

colors = ['red', 'green', 'blue']
for color in islice(cycle(colors), 7):
    print(color)
# خروجی: red, green, blue, red, green, blue, red
        

repeat(object, times=None)

یک مقدار ثابت رو times بار (یا بی‌نهایت بار اگه times نباشه) تکرار می‌کنه.


from itertools import repeat

for x in repeat('Python', 3):
    print(x)
# خروجی: Python, Python, Python
        

۲. تکرارکننده‌های ترکیبی (Combinatoric Iterators)

این دسته از توابع برای تولید ترکیبات و جایگشت‌های مختلف از یک مجموعه استفاده می‌شن. اگه داری روی مسائل احتمالاتی، رمزنگاری یا تولید رمز عبور کار می‌کنی، این توابع دستیارهای قدرتمندی هستن.

product(*iterables, repeat=1)

این تابع، ترکیب دکارتی (Cartesian product) چند تکرارپذیر رو برمی‌گردونه. یعنی همه حالت‌های ممکن از انتخاب یک عنصر از هر تکرارپذیر رو تولید می‌کنه. پارامتر repeat مشخص می‌کنه که هر تکرارپذیر چند بار تکرار بشه.


from itertools import product

# ترکیب دکارتی دو لیست
print(list(product('AB', 'CD')))
# خروجی: [('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D')]

# با repeat
print(list(product('AB', repeat=2)))
# خروجی: [('A', 'A'), ('A', 'B'), ('B', 'A'), ('B', 'B')]
        

permutations(iterable, r=None)

تمام جایگشت‌های ممکن از عناصر iterable رو برمی‌گردونه. اگه r مشخص بشه، جایگشت‌های به طول r تولید می‌شن. ترتیب اینجا مهمه و تکرار هم نداریم.


from itertools import permutations

print(list(permutations('ABC')))
# خروجی: [('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]

print(list(permutations('ABC', 2)))
# خروجی: [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
        

combinations(iterable, r)

ترکیبات منحصر به فرد (بدون در نظر گرفتن ترتیب) از عناصر iterable رو تولید می‌کنه. طول هر ترکیب r خواهد بود. این‌بار ترتیب مهم نیست.


from itertools import combinations

print(list(combinations('ABC', 2)))
# خروجی: [('A', 'B'), ('A', 'C'), ('B', 'C')]
        

combinations_with_replacement(iterable, r)

مثل combinations هست، ولی این بار انتخاب عناصر با جایگزینی صورت می‌گیره. یعنی می‌تونی یه عنصر رو چند بار انتخاب کنی.


from itertools import combinations_with_replacement

print(list(combinations_with_replacement('ABC', 2)))
# خروجی: [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
        

مقایسه توابع ترکیبی itertools
تابع توضیحات و مثال
product ترکیب دکارتی (Cartesian product) – ترتیب مهم است، تکرار می‌تواند اتفاق بیفتد.
مثال: list(product('AB', repeat=2)) ➡️ [('A', 'A'), ('A', 'B'), ('B', 'A'), ('B', 'B')]
permutations جایگشت‌ها (Permutations) – ترتیب مهم است، تکرار عناصر نیست.
مثال: list(permutations('ABC', 2)) ➡️ [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
combinations ترکیبات (Combinations) – ترتیب مهم نیست، تکرار عناصر نیست.
مثال: list(combinations('ABC', 2)) ➡️ [('A', 'B'), ('A', 'C'), ('B', 'C')]
combinations_with_replacement ترکیبات با جایگزینی – ترتیب مهم نیست، تکرار عناصر مجاز است.
مثال: list(combinations_with_replacement('ABC', 2)) ➡️ [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]

۳. تکرارکننده‌هایی که به اندازه ورودی محدود می‌شوند (Terminating Iterators)

این دسته از توابع، تا زمانی که ورودی‌شون تموم نشده باشه، خروجی تولید می‌کنن. اینا واقعاً همه‌کاره هستن و برای فیلتر کردن، گروه‌بندی و دستکاری دنباله‌ها خیلی به درد می‌خورن. این توابع جزو کدهای آماده و اسنیپت‌های بسیار کاربردی در هر پروژه پایتونی به حساب میان.

chain(*iterables)

چندین تکرارپذیر رو پشت سر هم وصل می‌کنه. انگار که همه رو یه لیست بزرگ کردی، بدون اینکه واقعاً لیست جدیدی بسازی.


from itertools import chain

list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
print(list(chain(list1, list2)))
# خروجی: [1, 2, 3, 'a', 'b', 'c']
        

compress(data, selectors)

عناصری از data رو برمی‌گردونه که مقدار متناظرشون در selectors (که باید یه تکرارپذیر از مقادیر Boolean باشه) True باشه.


from itertools import compress

letters = ['A', 'B', 'C', 'D']
booleans = [True, False, True, False]
print(list(compress(letters, booleans)))
# خروجی: ['A', 'C']
        

groupby(iterable, key=None)

این تابع جادوییه! عناصر متوالی یک تکرارپذیر رو بر اساس یک تابع کلید (key) گروه‌بندی می‌کنه. نکته مهم اینه که برای کارکرد صحیح، تکرارپذیر باید از قبل مرتب شده باشه.


from itertools import groupby

data = [('A', 1), ('A', 2), ('B', 3), ('B', 4), ('A', 5)]
data.sort(key=lambda x: x[0]) # حتما باید سورت بشه!
# خروجی بعد از سورت: [('A', 1), ('A', 2), ('A', 5), ('B', 3), ('B', 4)]

for key, group in groupby(data, lambda x: x[0]):
    print(f"Key: {key}, Group: {list(group)}")
# خروجی:
# Key: A, Group: [('A', 1), ('A', 2), ('A', 5)]
# Key: B, Group: [('B', 3), ('B', 4)]
        

islice(iterable, stop) or islice(iterable, start, stop[, step])

مثل اسلایس کردن لیست‌ها، ولی روی تکرارکننده‌ها. برای برش زدن قسمت‌های خاصی از یک تکرارکننده (مخصوصاً بی‌نهایت‌ها) فوق‌العاده است. مصرف حافظه ثابتی داره.


from itertools import count, islice

# 5 عدد اول از شمارنده بی‌نهایت
print(list(islice(count(), 5)))
# خروجی: [0, 1, 2, 3, 4]

# از ایندکس 2 تا 5 با گام 2
print(list(islice(range(10), 2, 8, 2)))
# خروجی: [2, 4, 6]
        

takewhile(predicate, iterable)

عناصر رو از iterable برمی‌گردونه تا زمانی که predicate (یه تابع که True/False برمی‌گردونه) برای عنصر فعلی True باشه. به محض اینکه False بشه، متوقف می‌شه و بقیه عناصر رو نادیده می‌گیره.


from itertools import takewhile

numbers = [1, 2, 3, 4, 1, 2, 3]
print(list(takewhile(lambda x: x < 4, numbers)))
# خروجی: [1, 2, 3] (بعد از 3، به 4 می‌رسه که شرط رو نقض می‌کنه و متوقف می‌شه)
        

dropwhile(predicate, iterable)

برعکس takewhile عمل می‌کنه. عناصر رو رد می‌کنه تا زمانی که predicate برای اولین بار False بشه. بعد از اون، همه عناصر باقی‌مانده رو برمی‌گردونه.


from itertools import dropwhile

numbers = [1, 2, 3, 4, 1, 2, 3]
print(list(dropwhile(lambda x: x < 4, numbers)))
# خروجی: [4, 1, 2, 3] (1, 2, 3 اولی رو رد می‌کنه تا به 4 برسه، از 4 به بعد رو برمی‌گردونه)
        

filterfalse(predicate, iterable)

این تابع، برعکس تابع filter() داخلی پایتون عمل می‌کنه؛ یعنی عناصری رو برمی‌گردونه که predicate برایشون False باشه.


from itertools import filterfalse

numbers = [1, 2, 3, 4, 5]
print(list(filterfalse(lambda x: x % 2 == 0, numbers))) # اعدادی که زوج نیستند (شرط True نیست)
# خروجی: [1, 3, 5]
        

accumulate(iterable, func=operator.add)

محاسبات تجمعی (cumulative) رو انجام می‌ده. یعنی هر بار نتیجه عملیات قبلی رو با عنصر فعلی ترکیب می‌کنه. اگه func رو مشخص نکنی، به صورت پیش‌فرض جمع (add) رو انجام می‌ده.


from itertools import accumulate
import operator

numbers = [1, 2, 3, 4, 5]
print(list(accumulate(numbers))) # جمع تجمعی
# خروجی: [1, 3, 6, 10, 15]

print(list(accumulate(numbers, operator.mul))) # ضرب تجمعی
# خروجی: [1, 2, 6, 24, 120]
        

tee(iterable, n=2)

از یک تکرارکننده، n کپی مستقل می‌سازه. خیلی به درد می‌خوره وقتی می‌خوای روی یه جریان داده، چندتا عملیات مختلف رو همزمان انجام بدی و نمی‌خوای داده‌ها رو چند بار بخونی یا تو حافظه کپی کنی. مهم اینه که بعد از ساختن کپی‌ها، از تکرارکننده اصلی دیگه استفاده نکنی.


from itertools import tee

data = iter(range(5))
it1, it2 = tee(data)

print(f"Iterator 1: {list(it1)}")
print(f"Iterator 2: {list(it2)}")
# خروجی:
# Iterator 1: [0, 1, 2, 3, 4]
# Iterator 2: [0, 1, 2, 3, 4]
        

استفاده از itertools در سناریوهای واقعی: کدنویسی هوشمندانه‌تر

حالا که با توابع مختلف آشنا شدی، وقتشه ببینیم چطور می‌تونیم اینا رو با هم ترکیب کنیم و برای حل مشکلات واقعی برنامه‌نویسی استفاده کنیم.

مثال: پیدا کردن زیردنباله‌هایی که جمع‌شان به یک مقدار خاص می‌رسد

فرض کن یه لیست از اعداد داری و می‌خوای تمام زیردنباله‌هایی رو پیدا کنی که جمع عناصرشون برابر با یه عدد خاص (مثلاً 10) بشه. این یه مشکل رایجه که با itertools خیلی شیک و بهاینه‌سازی حل می‌شه:


from itertools import combinations

numbers = [1, 2, 3, 4, 5, 6, 7]
target_sum = 10
found_subsequences = []

for r in range(1, len(numbers) + 1):
    for combo in combinations(numbers, r):
        if sum(combo) == target_sum:
            found_subsequences.append(combo)

print(f"زیردنباله‌ها با جمع {target_sum}: {found_subsequences}")
# خروجی: زیردنباله‌ها با جمع 10: [(3, 7), (4, 6), (1, 2, 7), (1, 3, 6), (1, 4, 5), (2, 3, 5), (1, 2, 3, 4)]
        

بهینه‌سازی حافظه و زمان اجرا

یکی از بزرگترین مزیت‌های itertools، مدیریت هوشمندانه حافظه است. چون توابع itertools تکرارکننده برمی‌گردونن (و نه لیست)، هر بار فقط یک عنصر رو تو حافظه نگه می‌دارن. این یعنی برای مجموعه داده‌های بزرگ، خبری از مصرف سرسام‌آور RAM نیست و برنامه‌هات با سرعت بیشتری اجرا می‌شن.

مثلاً، اگه بخوای 100 میلیون عدد رو تو یه لیست تولید کنی، پایتون کلی حافظه مصرف می‌کنه. اما اگه از itertools.count() با islice() استفاده کنی، حافظه مصرفی تقریباً صفر میشه و هر بار فقط عدد فعلی تو حافظه است.

عیب‌یابی سریع و راه‌حل‌ها (Troubleshooting)

ممکنه وقتی با itertools کار می‌کنی، به چندتا مشکل عادعی بربخوری. نگران نباش، ایناهاش راه‌حل‌هاشون:

مشکل ۱: حلقه بی‌نهایت با توابع count، cycle، repeat

اگه از این توابع بدون محدود کردن استفاده کنی، برنامه‌ات تا ابد ادامه پیدا می‌کنه و ممکنه سیستم رو قفل کنه.

راه‌حل: همیشه از islice() برای محدود کردن تعداد عناصر، یا از یک شرط منطقی در حلقه‌ات استفاده کن.


from itertools import count, islice

# بد: for i in count(): print(i) # حلقه بی‌نهایت
# خوب:
for i in islice(count(), 10):
    print(i) # فقط 10 بار چاپ می‌شود
        

مشکل ۲: groupby درست کار نمی‌کند

groupby فقط عناصر متوالی که کلید یکسانی دارند رو گروه‌بندی می‌کنه. اگه داده‌هات مرتب نباشن، نتیجه‌ای که می‌خوای رو نمی‌گیری.

راه‌حل: قبل از استفاده از groupby، حتماً داده‌ها رو بر اساس همون کلیدی که برای groupby استفاده می‌کنی، مرتب (sort) کن.


from itertools import groupby

data_unordered = [('A', 1), ('B', 3), ('A', 2)]
# بد: for key, group in groupby(data_unordered, lambda x: x[0]): ...

# خوب:
data_ordered = sorted(data_unordered, key=lambda x: x[0])
for key, group in groupby(data_ordered, lambda x: x[0]):
    print(f"Key: {key}, Group: {list(group)}")
        

مشکل ۳: مصرف بیش از حد حافظه با توابعی مثل list()

اگه خروجی یک تکرارکننده itertools رو بلافاصله تبدیل به لیست کنی (مثلاً list(permutations(...)))، ممکنه تمام قدرت itertools رو از بین ببری و باز هم با مشکل حافظه روبرو شی، مخصوصاً برای داده‌های بزرگ. توابعی مثل permutations و product می‌تونن خروجی‌های بسیار بزرگی داشته باشن.

راه‌حل: تا جای ممکن، روی خود تکرارکننده‌ها حلقه بزن یا از islice() برای گرفتن نمونه‌های کوچک استفاده کن. فقط در صورت لزوم و برای داده‌های قابل مدیریت، اون‌ها رو به لیست تبدیل کن.


from itertools import permutations, islice

# بد (برای ورودی بزرگ): all_perms = list(permutations(range(10))) # RAM پر میشه

# خوب:
# روی هر جایگشت به صورت جداگانه کار کن
for p in permutations(range(10), 3):
    # عملیات مورد نظر روی p
    pass

# یا فقط چندتاشو بگیر
print(list(islice(permutations(range(10)), 5))) # 5 جایگشت اول
        

مشکل ۴: یک تکرارکننده فقط یک بار قابل استفاده است

برخلاف لیست‌ها، اکثر تکرارکننده‌ها “مصرف‌شونده” هستن. یعنی اگه یه بار روی اونا حلقه بزنی، خالی می‌شن و برای بار دوم دیگه چیزی برای تکرار ندارن.

راه‌حل: اگه به چند بار استفاده از یک تکرارکننده نیاز داری، از itertools.tee() برای ساختن کپی‌های مستقل استفاده کن. یادت باشه که بعد از ساخت کپی، از تکرارکننده اصلی دیگه استفاده نکنی و فقط با کپی‌ها کار کنی.


from itertools import tee

data = iter([1, 2, 3])
it1, it2 = tee(data)

# it1 را مصرف می‌کنیم
print(list(it1)) # خروجی: [1, 2, 3]

# حالا it2 را مصرف می‌کنیم، که کاملا مستقل است
print(list(it2)) # خروجی: [1, 2, 3]
        

حرف آخر: itertools، یار همیشه همراهت

خب، رسیدیم به پایان این سفر جذاب تو دنیای itertools. دیدی که چقدر این ماژول می‌تونه قدرت و انعطاف‌پذیری به کدهات اضافه کنه، خصوصاً برای کارهایی که نیاز به کار با دنباله‌ها و تولید داده‌ها به صورت کارآمد دارن. از تولید اعداد بی‌نهایت تا ترکیبات پیچیده، itertools یه جعبه ابزار حرفه‌ایه که هر برنامه‌نویس پایتونی باید تو جیبش داشته باشه.

حواست باشه که قدرت واقعی این توابع وقتی نمایان می‌شه که اونا رو با هم ترکیب کنی و برای حل مسائل خاصت به کار بگیری. پس دست به کار شو، این کدها رو امتحان کن و از اینکه چقدر می‌تونی کدهای تمیز و سریع بنویسی، لذت ببر.

پرسش‌های متداول (FAQ) درباره itertools

Q: ماژول itertools برای چه کاری استفاده می‌شود؟

A: itertools مجموعه‌ای از توابع است که برای ساختن تکرارکننده‌های کارآمد و با مصرف حافظه پایین، خصوصاً برای عملیات‌های تکراری روی دنباله‌ها و مجموعه‌ها، استفاده می‌شود. این توابع به شما کمک می‌کنند تا کدهای کوتاه‌تر و سریع‌تری بنویسید.

Q: آیا itertools برای داده‌های بزرگ مناسب است؟

A: بله، قطعاً! یکی از بزرگترین مزیت‌های itertools همین است. توابع آن به صورت تنبل (lazily) عمل می‌کنند و هر بار فقط یک عنصر را در حافظه نگه می‌دارند، بنابراین برای کار با مجموعه داده‌های بسیار بزرگ که در حافظه جا نمی‌شوند، عالی هستند.

Q: فرق itertools.permutations با itertools.combinations چیست؟

A: permutations (جایگشت‌ها) ترتیب عناصر را در نظر می‌گیرد. یعنی (A, B) و (B, A) را دو جایگشت متفاوت می‌داند. اما combinations (ترکیبات) ترتیب را در نظر نمی‌گیرد و (A, B) و (B, A) را یک ترکیب می‌داند.

 

Table of Contents

آخرین نوشته‌ها