کار کردن با بخشی از یک لیست

در فصل ۳ روش دسترسی به تک تک اعضای یک لیست و در این فصل کار کردن با تمام اعضای آن را آموختید. در عین حال شما می‌توانید با گروه مشخّصی از اعضای یک لیست کار کنید که پایتون آن را برش می‌نامد.

ساختن برشی از لیست

برای برش دادن یک لیست شاخص آغازی و پایانی اعضای مورد نظر خود را مشخّص می‌کنید. همانند تابع range() پایتون پیش از رسیدن به آخرین عضوِ مشخّص شده توقّف می‌کند. برای بریدن سه عضو اوّل یک لیست باید شاخص‌های ۰ تا ۳ را درخواست کنید که اعضای ۰، ۱ و ۲ را برمی‌گرداند.

مثال زیر درباره‌ی لیستی از بازیکن‌های یک تیم است:

1
2
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3])

کد در 1 برشی از لیست را چاپ می‌کند که شامل سه بازیکن اوّل است. در خروجی ساختار لیست حفظ شده و شامل سه بازیکن است:

1
['charles', 'martina', 'michael']

می‌توانید هر زیرمجموعه‌ای را از یک لیست تولید کنید. مثلاً اگر برشی از لیست را شامل اعضای دوم، سوم و چهارم بخواهید می‌توانید آن را از شاخص ۱ آغاز و به شاخص ۴ ختم کنید:

1
2
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[1:4])

این بار برش از ‘martina’ شروع و با ‘florence’ تمام می‌شود:

1
['martina', 'michael', 'florence']

اگر شاخص اوّل برش را حذف کنید، پایتون برش را به طور خودکار از آغاز لیست شروع می‌کند:

1
2
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[:4])

بدونِ شاخصِ آغازین، پایتون از اوّلِ لیست شروع می‌کند:

1
['charles', 'martina', 'michael', 'florence']

از همین ترکیب می‌توانید برای برش‌های انتهایی لیست استفاده کنید. برای نمونه اگر برشی شامل همه‌ی اعضا از شاخص سوم تا پایان لیست را بخواهید می‌توانید شاخص شروع را ۲ گذاشته و شاخص پایان را حذف کنید:

1
2
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[2:])

پایتون عضو سوم تا پایان را برمی‌گرداند:

1
['michael', 'florence', 'eli']

به این ترتیب می‌توانید صرف نظر از طول لیست، تمام اعضای بین یک شاخص خاص و پایان آن را در خروجی داشته باشید. به خاطر بیاورید که شاخص منفی می‌توانست عضوی را در فاصله‌ی مشخّصی از پایان لیست برگرداند. پس به کمک آن می‌توانید برش‌هایی از انتهای لیست تولید کنید. برای مثال اگر بخواهیم سه بازیکنِ آخرِ ترکیبِ تیم را برگردانیم از برش players[-3:] استفاده می‌کنیم:

1
2
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[-3:])

این مثال نام سه بازیکن آخر را چاپ می‌کند و با افزایش تعداد بازیکنانِ لیست هم بدون مشکل کار خواهد کرد.

نکته
هنگام تعریف برش می‌توانید عدد سومی هم داخل کروشه بنویسید. این عدد مشخّص می‌کند که پایتون چند عضو را در بازه‌ی مشخّص‌شده نادیده بگیرد. (مانند آن‌چه که در تابع range بود.)

حلقه زدن در یک برش

اگر بخواهید تنها در زیرمجموعه‌ای از اعضای یک لیست حلقه بزنید می‌توانید از یک برش در حلقه‌ی for استفاده کنید. در مثال زیر در سه بازیکن اوّل حلقه می‌زنیم و نام آن‌ها را به عنوان یک ترکیبِ تیم ساده چاپ می‌کنیم:

1
2
3
4
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print("Here are the first three players on my team:")
for player in players[:3]:
    print(player.title())

پایتون در 1 به جای حلقه زدن در کل لیست، تنها در سه نام اول می‌چرخد:

1
2
3
4
Here are the first three players on my team:
Charles
Martina
Michael

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

کپی کردن یک لیست

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

برای کپی کردن یک لیست می‌توانید با حذف کردن شاخص‌های ابتدایی و پایانی ([:]) برشی از آن را تهیه کنید که شامل تمام اعضای لیست اوّلّیه است. این کار به پایتون می‌گوید که برشی از لیست تهیه کند که از عضو اول شروع و به عضو آخر ختم می‌شود و باعث ایجاد یک کپی از کل لیست می‌شود.

برای مثال فرض کنید که لیستی از غذاهای مورد علاقه‌مان موجود است و می‌خواهیم لیستی جداگانه و مشابه برای یک دوست درست کنیم. دوستمان تمام غذاهای مورد علاقه‌ی ما را دوست دارد در نتیجه می‌توانیم لیست او را با کپی کردن لیست خود درست کنیم:

1
2
3
4
5
6
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
print("My favorite foods are:")
print(my_foods)
print("\nMy friend's favorite foods are:")
print(friend_foods)

در 1 لیستی از غذاهایی را که دوست داریم به نام my_foods درست کرده‌ایم. در 2 لیست جدیدی به نام friend_foods می‌سازیم. با درخواست برشی از my_foods بدون مشخّص کردن هیچ شاخصی و ذخیره کردن آن در friend_foods، یک کپی از my_foods ایجاد می‌کنیم. اگر هر دو لیست را چاپ کنیم می‌بینیم که هر دو دربرگیرنده‌ی غذاهای مشابهی هستند:

1
2
3
4
My favorite foods are:
['pizza', 'falafel', 'carrot cake']
My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake']

برای این که ثابت کنیم واقعاً دو لیست جداگانه داریم یک غذای جدید به هر یک از لیست‌ها اضافه می‌کنیم تا نشان دهیم که هر لیست غذاهای مورد علاقه‌ی یک نفر را به صورت جداگانه نگه می‌دارد:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]

my_foods.append('cannoli')
friend_foods.append('ice cream')

print("My favorite foods are:")
print(my_foods)

print("\nMy friend's favorite foods are:")
print(friend_foods)

در 1 همانند قبل، اعضای اوّلیّه‌ی داخل my_foods را در لیست جدید friend_foods کپی کردیم. در ادامه یک غذای جدید به هر لیست اضافه می‌کنیم: در 2 ‘cannoli’ را به my_foods و در 3 ‘ice cream’ را به friend_foods افزودیم. سپس هر دو لیست را چاپ می‌کنیم تا ببینیم هر کدام از این غذاها به لیست مناسب اضافه شده‌اند یا نه:

1
2
3
4
5
My favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli']

My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'ice cream']

خروجی نشان می‌دهد که ‘cannoli’ اکنون در لیست غذاهای مورد علاقه‌ی ما وجود دارد امّا ‘ice cream’ اینچنین نیست. در 5 می‌بینیم که ‘ice cream’ در لیست دوستمان هست امّا ‘cannoli’ نیست. اگر صرفاً و به سادگی متغیّر friend_foods را برابر با my_foods قرار می‌دادیم، منجر به ایجاد دو لیست جداگانه نمی‌شد. برای مثال اینجا می‌بینیم اگر لیستی را بدون استفاده از برش کپی کنیم چه اتّفاقی می‌افتد:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
my_foods = ['pizza', 'falafel', 'carrot cake']

# This doesn't work:
friend_foods = my_foods
my_foods.append('cannoli')
friend_foods.append('ice cream')

print("My favorite foods are:")
print(my_foods)

print("\nMy friend's favorite foods are:")
print(friend_foods)

در 1 به جای کپی کردن my_foods در friend_foods، صرفاً این دو متغیّر را برابر با یکدیگر قرار دادیم. این دستور به پایتون می‌گوید که متغیّر جدید friend_foods را به لیستی ارتباط دهد که خود قبلاً با my_foods مرتبط بوده است. بنابراین الان هر دو متغیّر به یک لیست مشابه اشاره می‌کنند. در نتیجه اگر ‘cannoli’ را به my_foods اضافه کنید این عضو در friend_foods نیز ظاهر خواهد شد. به طور مشابه اگر ‘ice cream’ را فقط به friend_foods اضافه کنید در هر دو لیست دیده خواهد شد.

خروجی نشان می‌دهد که هر دو لیست یکسان هستند و این چیزی نیست که ما می‌خواستیم:

1
2
3
4
5
My favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']

My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']
نکته
الان نگران جزئیات این مثال نباشید. اساساً هر جا هنگام کپی کردنِ یک لیست رفتاری غیرمنتظره دیدید مطمئن شوید که همانند مثال اوّل، از یک برش استفاده کرده‌اید.

خودآزمایی

برش‌ها

به یکی از برنامه‌هایی که در این فصل نوشته‌اید چند خط اضافه کنید تا کارهای زیر را انجام دهد:

  • پیام The first three items in the list are: و سپس به کمک یک برش سه عضو اوّل لیست برنامه را چاپ کند.
  • پیام Three items from the middle of the list are: و سپس به کمک یک برش سه عضو میانی لیست برنامه را چاپ کند.
  • پیام The last three items in the list are: و سپس به کمک یک برش سه عضو آخر لیست برنامه را چاپ کند.

پیتزاهای من، پیتزاهای تو

با شروع از برنامه‌ی تمرین ۴-۱ یک کپی از لیست پیتزاها ایجاد کنید و آن را friend_pizzas بنامید. سپس این کارها را انجام دهید:

  • یک پیتزای جدید به لیست اصلی اضافه کنید. پیام My favorite pizzas are: و در ادامه به کمک یک حلقه‌ی for لیست اول را چاپ کنید. پیام My friend's pizzas are: و با یک حلقه‌ی for لیست دوم را چاپ کنید. مطمئن شوید که هر پیتزا در لیست مناسب ذخیره شده باشد.

حلقه‌های بیشتر

در تمام نسخه‌های foods.py برای صرفه‌جویی در فضا از به‌کارگیری حلقه‌ی for برای چاپ لیست پرهیز شده است. یکی از نسخه‌ها را انتخاب کنید و دو حلقه‌ی for برای چاپ کردن هر کدام از لیست‌ها به آن بیفزایید.