کتابخانه collections در پایتون
ماژول collections یکی از ابزارهای پایهای و پرکاربرد در پایتون است که ساختمان دادههای پیشرفتهتر و بهینهتری را نسبت به لیست و دیکشنری ساده در اختیار توسعهدهنده قرار میدهد. این مقاله به معرفی کلاسهای اصلی این ماژول، مثالهای واقعی، نکات عملکردی و بهترین کاربردها میپردازد.
چرا از collections استفاده کنیم؟
هدف اصلی این ماژول ارائهی ساختارهایی است که برای مسائلی مانند شمارش، صف و پشته، نگهداری ترتیب درج، نگاشت چندگانه و نامگذاری فیلدها مناسبتر و سریعتر هستند. استفاده درست از این کلاسها میتواند خوانایی کد و کارایی را بهطرز محسوسی افزایش دهد.
مقدمهای بر کلاسهای مهم
- Counter: شمارش فرکانس عناصر
- defaultdict: دیکشنری با مقدار پیشفرض
- deque: صف/پشته دوطرفه با عملیات O(1) در ابتدا و انتها
- namedtuple: تاپل نامدار با فیلدهای قابل دسترسی بهصورت صفت
- OrderedDict: دیکشنری با حفظ ترتیب درج (در پایتون جدید dict این رفتار را دارد اما OrderedDict متدهای اضافی دارد)
- ChainMap: ترکیب چند دیکشنری برای جستجو پشتسرهم
Counter — شمارش کارآمد
from collections import Counter
data = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
c = Counter(data)
print(c.most_common(2)) # [('apple', 3), ('banana', 2)]
در این مثال، Counter فرکانس هر عنصر را محاسبه و متد most_common دو عنصر پرتکرار را برمیگرداند. Counter برای تحلیل لاگها، شمارش کلمات و تجزیهی دادههای آماری ایدهآل است.
defaultdict — جلوگیری از خطای KeyError
from collections import defaultdict
d = defaultdict(int)
words = ["cat","dog","cat"]
for w in words:
d[w] += 1
print(dict(d)) # {'cat': 2, 'dog': 1}
در این کد، اگر کلیدی وجود نداشته باشد، مقدار پیشفرض صفر (از نوع int) ایجاد میشود. این روش معمولاً خواناتر و امنتر از استفاده از شرطها یا try/except است.
deque — صف و پشته سریع
from collections import deque
q = deque()
q.append('a')
q.append('b')
q.appendleft('z')
print(q) # deque(['z', 'a', 'b'])
q.pop()
print(q) # deque(['z', 'a'])
q.popleft()
print(q) # deque(['a'])
deque برای پیادهسازی صف (FIFO) و پشته (LIFO) مناسب است؛ زیرا عملیات افزودن/حذف از ابتدا یا انتها با پیچیدگی زمانی O(1) انجام میشود. از لیست برای pop(0) یا insert(0, x) استفاده نکنید چون هزینهبر است.
namedtuple — خوانایی و سبکتر از کلاس
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 10 20
namedtuple ترکیبی از تاپل و کلاس سبک است: مقادیر ایمن، قابلخواندن و حافظه-بهرهور. اگر به قابلیت تغییر (mutable) نیاز دارید، از dataclass یا کلاس استفاده کنید؛ namedtuple مقادیر را غیرقابلتغییر نگه میدارد.
OrderedDict — ترتیب و متدهای کمکی
from collections import OrderedDict
od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3
od.move_to_end('b')
print(list(od.keys())) # ['a', 'c', 'b']
در نسخههای جدید پایتون استاندارد dict نیز ترتیب درج را حفظ میکند، اما OrderedDict متدهایی مانند move_to_end و popitem(last=False) را ارائه میدهد که برای الگوریتمهایی که نیاز به جابجایی ترتیب دارند مفید است (مثلاً الگوریتم LRU cache ساده).
ChainMap — ترکیب چند نگاشت
from collections import ChainMap
defaults = {'theme': 'light', 'lang': 'en'}
user = {'lang': 'fa'}
cfg = ChainMap(user, defaults)
print(cfg['theme'], cfg['lang']) # light fa
ChainMap امکان ترکیب چند دیکشنری را بدون کپیبرداری فراهم میکند؛ مفید در مدیریت تنظیمات (defaults و user overrides) یا اسکوپهای مختلف برنامهنویسی.
مقایسه عملکرد و نکات حرفهای
| کلاس | کاربرد | مزیت کلیدی |
|---|---|---|
| Counter | شمارش فرکانس | متدهای آماده مثل most_common |
| defaultdict | دیکشنری با مقدار پیشفرض | کاهش خطا و شرطها |
| deque | صف/پشته | عملیات O(1) در ابتدا/انتها |
| namedtuple | ساختار داده سبک | خوانایی و ثابت بودن |
| OrderedDict | دیکشنری مرتب | متدهای ترتیبدهی اضافی |
نمونههای واقعی و الگوهای کاربردی
- آنالیز متن: استفاده از Counter برای شمارش کلمات پرتکرار.
- پیادهسازی صف پیام: استفاده از deque برای مصرفکننده و تولیدکننده.
- تنظیمات برنامه: ChainMap برای ترکیب تنظیمات پیشفرض و کاربر.
- کش LRU ساده: OrderedDict با popitem و move_to_end.
مثال: پیادهسازی LRU cache ساده با OrderedDict
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity=3):
self.cache = OrderedDict()
self.capacity = capacity
def get(self, key):
if key not in self.cache:
return -1
value = self.cache.pop(key)
self.cache[key] = value # move to end (most recently used)
return value
def put(self, key, value):
if key in self.cache:
self.cache.pop(key)
elif len(self.cache) >= self.capacity:
self.cache.popitem(last=False) # remove least recently used
self.cache[key] = value
این کلاس از OrderedDict برای نگهداری ترتیب دسترسی استفاده میکند. متد get آیتم را به انتها منتقل میکند و متد put در صورت پر بودن کش، آیتم قدیمیترین را حذف میکند. این الگو ساده و کارا برای آموزش LRU است؛ در پروژههای واقعی از functools.lru_cache یا پیادهسازیهای بهینهتر استفاده کنید.
نکات بهینهسازی و هشدارها
- در پایتون 3.7+، dict مرتب است؛ استفاده از OrderedDict تنها زمانی لازم است که به متدهای خاص آن نیاز داشته باشید.
- Counter مناسب عملیات تکتردی و سریع شمارش است؛ برای شمارش در دادههای بسیار بزرگ از itertools یا پردازش دستهای استفاده کنید.
- deque برای کارآمدی حافظه و زمان در صفها و اتصالهای دوطرفه برتر از لیست است.
- namedtuple حافظه کمتر و سرعت بالاتر نسبت به کلاس معمولی دارد، اما غیرقابلتغییر است؛ اگر نیاز به قابلیت تغییر دارید، dataclass گزینه بهتری است.
جمعبندی
ماژول collections مجموعهای از ساختارهای دادهای کارا و خوانا را ارائه میدهد که در اکثر پروژههای عملی کاربرد دارند. آشنایی با این کلاسها و انتخاب درست آنها میتواند موجب سادهتر شدن پیادهسازیها و بهبود کارایی شود. توصیه میشود هنگام مواجهه با مسائلی مانند شمارش، صف/پشته، نگهداری ترتیب یا ترکیب تنظیمات، ابتدا بررسی کنید آیا یکی از ابزارهای collections پاسخ مناسب را ارائه میدهد یا خیر.
آیا این مطلب برای شما مفید بود ؟




