فصل ۴: ساختارهای داده — list، tuple، dict، set و collections

list: متدها، دام a = b و کپی سطحی در برابر عمیق

پرکاربردترین ساختار داده

list دنباله‌ای مرتب و تغییرپذیر (mutable) از اشیاست که با کروشه ساخته می‌شود: sizes = [6, 12, 9]. اعضا می‌توانند از هر نوعی باشند، اما در عمل بهتر است یک لیست از اشیای هم‌جنس باشد (همه قیمت، همه نام). اندیس‌گذاری و برش دقیقاً مثل رشته است، با این تفاوت که می‌توانید عضوها را تغییر دهید: sizes[0] = 8.

متدهای اصلی

متدکاربازگشتی
append(x)افزودن یک عضو به انتهاNone
extend(iterable)افزودن همه‌ی اعضای یک مجموعهNone
insert(i, x)درج در جایگاه iNone
pop(i=-1)برداشتن و برگرداندن عضوعضو حذف‌شده
remove(x)حذف اولین x (نبودش ValueError)None
sort() / reverse()مرتب/معکوس کردن درجاNone
index(x) / count(x)جایگاه / تعداد تکرارعدد

به ستون آخر دقت کنید: متدهایی که لیست را تغییر می‌دهند None برمی‌گردانند. خطای کلاسیک sizes = sizes.sort() لیست شما را به None تبدیل می‌کند. اگر نسخه‌ی مرتب‌شده‌ی جدید می‌خواهید، از sorted(sizes) استفاده کنید.

دام a = b

یادتان هست متغیر فقط برچسب است؟ این‌جا اهمیتش آشکار می‌شود:

today = ["KSH-101", "TBZ-220"]
backup = today              # کپی نیست! دو برچسب روی یک لیست
today.append("MSH-310")
print(backup)               # ['KSH-101', 'TBZ-220', 'MSH-310']
print(backup is today)      # True

برای کپی واقعی یکی از این‌ها را بنویسید: today.copy()، list(today) یا today[:].

کپی سطحی در برابر عمیق

همه‌ی روش‌های بالا کپی سطحی (shallow) می‌سازند: خود لیست جدید است، اما اگر اعضا خودشان لیست یا دیکشنری باشند، همان اشیای قبلی به اشتراک گذاشته می‌شوند.

import copy

orders = [["KSH-101", 6], ["TBZ-220", 12]]
shallow = orders.copy()
shallow[0][1] = 99          # زیرلیست مشترک است
print(orders[0])            # ['KSH-101', 99]  — اصل هم عوض شد!

deep = copy.deepcopy(orders)
deep[1][1] = 0
print(orders[1])            # ['TBZ-220', 12]  — دست‌نخورده

دام ضرب لیست تودرتو

grid = [[0] * 3] * 3        # سه برچسب روی یک زیرلیست!
grid[0][0] = 1
print(grid)                 # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]

grid = [[0] * 3 for _ in range(3)]   # درست: سه زیرلیست مستقل

ضرب لیست اعداد مشکلی ندارد ([0] * 5)، چون اعداد تغییرناپذیرند. مشکل فقط وقتی است که عضو تکرارشونده خودش تغییرپذیر باشد.

نکته‌هایی که کمتر کسی می‌داند

  • items.append([1, 2]) یک عضو (یک لیست) اضافه می‌کند، اما items += "ab" دو عضو 'a' و 'b'؛ چون += روی لیست همان extend است و رشته را حرف‌به‌حرف باز می‌کند.
  • pop(0) و insert(0, x) روی لیست بزرگ کندند (همه‌ی اعضا جابه‌جا می‌شوند)؛ برای صف از collections.deque استفاده کنید.
  • del items[1:3] یک بازه را حذف می‌کند و items[1:3] = ["x"] بازه را با تعداد متفاوتی عضو جایگزین می‌کند.
  • x in big_list همه‌ی اعضا را یکی‌یکی بررسی می‌کند؛ اگر زیاد عضویت می‌پرسید، یک set بسازید که تقریباً فوری جواب می‌دهد.
  • list.sort() «پایدار» است: عضوهای با کلید برابر ترتیب قبلی‌شان را حفظ می‌کنند؛ پس می‌توانید در دو مرحله، اول بر اساس معیار فرعی و بعد اصلی مرتب کنید.

برای ذخیره‌ی پیشرفت و شرکت در آزمون، وارد شوید — رایگان است.