ابزارهای آماده برای کارهای تکراری
ماژول collections در کتابخانهی استاندارد، نسخههای تخصصی dict، tuple و list را دارد که کدهای رایج را کوتاهتر، سریعتر و کمخطاتر میکنند. هر برنامهنویس پایتون باید این چهار ابزار را بشناسد.
Counter: شمارش در یک خط
from collections import Counter
sold = ["کاشان", "تبریز", "کاشان", "مشهد", "کاشان", "تبریز"]
c = Counter(sold)
print(c) # Counter({'کاشان': 3, 'تبریز': 2, 'مشهد': 1})
print(c.most_common(2)) # [('کاشان', 3), ('تبریز', 2)]
print(c["اصفهان"]) # 0 — کلید نبود، KeyError نمیدهد
c.update(["مشهد", "مشهد"]) # افزودن شمارش
words = Counter("فرش دستباف کاشان فرش ماشینی".split())
print(sum(c.values())) # جمع کل
Counter از جمع و تفریق هم پشتیبانی میکند: farvardin + ordibehesht فروش دو ماه را جمع میکند و stock - sold موجودی باقیمانده را میدهد (نتیجههای صفر و منفی حذف میشوند).
defaultdict: دیکشنری با مقدار پیشفرض خودکار
from collections import defaultdict
by_city = defaultdict(list)
for city, code in [("کاشان", "K1"), ("تبریز", "T1"), ("کاشان", "K2")]:
by_city[city].append(code) # بدون get و setdefault
totals = defaultdict(int) # int() یعنی 0
for city, amount in [("کاشان", 5), ("کاشان", 3)]:
totals[city] += amount
آرگومان defaultdict یک تابع سازنده است (list، int، set)، نه یک مقدار. هر بار کلید ناموجودی خوانده شود، آن تابع صدا زده میشود.
namedtuple: tuple با نام فیلد
from collections import namedtuple
Rug = namedtuple("Rug", "code width length material")
r = Rug("KSH-101", 200, 300, "ابریشم")
print(r.width * r.length) # 60000 — بهجای r[1] * r[2]
print(r._asdict()) # تبدیل به dict
r2 = r._replace(width=250) # نسخهی جدید؛ اصلی تغییرناپذیر است
namedtuple برای رکوردهای سبک و تغییرناپذیر عالی است. اگر به مقدار پیشفرض، متد یا تغییرپذیری نیاز داشتید، سراغ dataclass بروید (فصل ۷).
deque: صف دوطرفه
from collections import deque
recent = deque(maxlen=3) # فقط سه عضو آخر نگه داشته میشود
for code in ["K1", "K2", "K3", "K4"]:
recent.append(code)
print(recent) # deque(['K2', 'K3', 'K4'], maxlen=3)
queue = deque(["سفارش ۱", "سفارش ۲"])
queue.append("سفارش ۳") # ورود از انتها
first = queue.popleft() # خروج از ابتدا — سریع
| ابزار | جایگزین چه کدی |
|---|---|
| Counter | d[k] = d.get(k, 0) + 1 در حلقه |
| defaultdict | d.setdefault(k, []).append(v) |
| namedtuple | tuple با اندیسهای جادویی r[2] |
| deque | list.pop(0) و list.insert(0, x) |
نکتههایی که کمتر کسی میداند
- خواندن کلید ناموجود از defaultdict آن کلید را میسازد؛ حتی یک
print(d["x"])ساده دیکشنری را بزرگ میکند. برای بررسی، از"x" in dاستفاده کنید. Counter("کاشان")حروف را میشمارد، نه کلمه را؛ برای کلمه اولsplit()بزنید.deque(maxlen=n)سادهترین راه ساختن «n رکورد آخر» یا تاریخچهی محدود است؛ عضوهای قدیمی خودکار بیرون میافتند.Counter.total()(3.10+) جمع همهی شمارشها را میدهد و ازsum(c.values())خواناتر است.- قبل از json.dump کردن defaultdict، آن را با
dict(d)تبدیل کنید تا خروجی و repr تمیز باشد.