منابع ترجمه · Think Python · فصل ۹

فهرست‌ها (فصل ۹ Think Python)

۱۷ دقیقه مطالعه · به‌روزرسانی ۲ آبان ۱۴۰۵

منبع اصلی: Think Python, Chapter 9: Lists — Allen B. Downey

💡 این صفحه مثل یک نوت‌بوک Jupyter است: متغیر و تابعی که در یک سلول تعریف شود، در سلول‌های بعدی همین صفحه در دسترس است. سلول‌ها را به ترتیب اجرا کنید، یا با «⏮ تا اینجا» همهٔ سلول‌های قبلیِ اجرانشده را یک‌جا اجرا کنید.

دو نکته درباره‌ی این ترجمه: (۱) کتاب اصلی در چند مثال، رشته‌هایی را به‌عنوان نمونه به کار می‌برد که از یک اسکچ طنز مشهور گرفته شده‌اند؛ در این ترجمه آن‌ها را با رشته‌های ساده‌ی خودم جایگزین کرده‌ام، بدون تغییر در مفهوم مثال‌ها. (۲) خروجی‌های نمایش‌داده‌شده‌ی زیر کدها را با اجرای همین کدها (روی فایل words.txt کتاب) به دست آورده‌ام.

این فصل یکی از مفیدترین نوع‌های داخلی پایتون، یعنی فهرست‌ها (lists) را معرفی می‌کند. همچنین درباره‌ی شیءها بیشتر یاد می‌گیرید و اینکه وقتی چند متغیر به یک شیء اشاره می‌کنند چه اتفاقی می‌افتد.

در تمرین‌های انتهای فصل، یک فهرست کلمه می‌سازیم و از آن برای جست‌وجوی کلمه‌های خاص، مثل کلمه‌های متقارن (palindrome) و آناگرام (anagram) استفاده می‌کنیم.

۹.۱. فهرست یک دنباله است

مثل رشته، فهرست (list) دنباله‌ای از مقدارهاست. در رشته مقدارها نویسه‌اند؛ در فهرست می‌توانند از هر نوعی باشند. مقدارهای داخل فهرست عنصر (element) نامیده می‌شوند.

چند راه برای ساختن یک فهرست جدید وجود دارد؛ ساده‌ترین راه محصور کردن عنصرها در کروشه ([ و ]) است. برای مثال، این فهرستی از دو عدد صحیح است.

numbers = [42, 123]

و این فهرستی از سه رشته است.

cheeses = ['Cheddar', 'Edam', 'Gouda']

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

t = ['spam', 2.0, 5, [10, 20]]

فهرستی که داخل فهرست دیگر است تودرتو (nested) نامیده می‌شود.

فهرستی که هیچ عنصری ندارد فهرست تهی نامیده می‌شود؛ می‌توانید آن را با کروشه‌ی خالی، []، بسازید.

empty = []

تابع len طول فهرست را برمی‌گرداند.

len(cheeses)
3

طول فهرست تهی 0 است.

len(empty)
0

شکل زیر نمودار وضعیت cheeses، numbers و empty را نشان می‌دهد.

(در کتاب اصلی اینجا نمودار رسم شده است: هر فهرست به‌صورت یک جعبه با کلمه‌ی «list» بیرون آن و عنصرهای شماره‌دار داخل آن؛ cheeses سه عنصر، numbers دو عنصر و empty هیچ عنصری ندارد.)

فهرست‌ها با جعبه‌هایی نشان داده می‌شوند که کلمه‌ی «list» بیرون آن‌ها و عنصرهای شماره‌دار فهرست داخل آن‌هاست.

۹.۲. فهرست‌ها تغییرپذیرند

برای خواندن یک عنصر از فهرست، می‌توانیم از عملگر کروشه استفاده کنیم. اندیس اولین عنصر 0 است.

cheeses[0]
'Cheddar'

برخلاف رشته‌ها، فهرست‌ها تغییرپذیر (mutable) هستند. وقتی عملگر کروشه در سمت چپ یک نسبت‌دهی بیاید، مشخص می‌کند کدام عنصر فهرست مقدار جدید می‌گیرد.

numbers[1] = 17
numbers
[42, 17]

عنصر دوم numbers که قبلاً 123 بود، اکنون 17 است.

اندیس‌های فهرست مثل اندیس‌های رشته کار می‌کنند:

  • هر عبارت صحیحی می‌تواند به‌عنوان اندیس به کار رود.

  • اگر سعی کنید عنصری را که وجود ندارد بخوانید یا بنویسید، IndexError می‌گیرید.

  • اگر اندیس مقدار منفی داشته باشد، از انتهای فهرست به عقب می‌شمارد.

عملگر in روی فهرست‌ها هم کار می‌کند – بررسی می‌کند که آیا عنصر داده‌شده در هر جای فهرست هست یا نه.

'Edam' in cheeses
True
'Wensleydale' in cheeses
False

اگرچه یک فهرست می‌تواند فهرست دیگری را در بر داشته باشد، فهرست تودرتو همچنان یک عنصر به حساب می‌آید – پس در فهرست زیر فقط چهار عنصر وجود دارد.

t = ['spam', 2.0, 5, [10, 20]]
len(t)
4

و 10 عنصر t به حساب نمی‌آید، چون عنصر یک فهرست تودرتوست، نه t.

10 in t
False

۹.۳. برش‌های فهرست

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

letters = ['a', 'b', 'c', 'd']
letters[1:3]
['b', 'c']

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

letters[:2]
['a', 'b']

اگر دومی را حذف کنید، برش تا انتها می‌رود.

letters[2:]
['c', 'd']

پس اگر هر دو را حذف کنید، برش یک کپی از کل فهرست است.

letters[:]
['a', 'b', 'c', 'd']

راه دیگر برای کپی کردن یک فهرست استفاده از تابع list است.

list(letters)
['a', 'b', 'c', 'd']

چون list نام یک تابع داخلی است، باید از استفاده از آن به‌عنوان نام متغیر پرهیز کنید.

۹.۴. عملیات روی فهرست‌ها

عملگر + فهرست‌ها را الحاق می‌کند.

t1 = [1, 2]
t2 = [3, 4]
t1 + t2
[1, 2, 3, 4]

عملگر * یک فهرست را به تعداد مشخصی تکرار می‌کند.

['spam'] * 4
['spam', 'spam', 'spam', 'spam']

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

sum(t1)
3

و min و max کوچک‌ترین و بزرگ‌ترین عنصر را پیدا می‌کنند.

min(t1)
1
max(t2)
4

۹.۵. متدهای فهرست

پایتون متدهایی دارد که روی فهرست‌ها عمل می‌کنند. برای مثال، append یک عنصر جدید به انتهای فهرست اضافه می‌کند:

letters.append('e')
letters
['a', 'b', 'c', 'd', 'e']

extend یک فهرست را به‌عنوان آرگومان می‌گیرد و همه‌ی عنصرهایش را اضافه می‌کند:

letters.extend(['f', 'g'])
letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']

دو متد برای حذف عنصرها از فهرست وجود دارد. اگر اندیس عنصری را که می‌خواهید بدانید، می‌توانید از pop استفاده کنید.

t = ['a', 'b', 'c']
t.pop(1)
'b'

مقدار بازگشتی عنصری است که حذف شده است. و می‌توانیم تأیید کنیم که فهرست تغییر کرده است.

t
['a', 'c']

اگر عنصری را که می‌خواهید حذف کنید می‌شناسید (اما اندیسش را نمی‌دانید)، می‌توانید از remove استفاده کنید:

t = ['a', 'b', 'c']
t.remove('b')

مقدار بازگشتی remove برابر None است. اما می‌توانیم تأیید کنیم که فهرست تغییر کرده است.

t
['a', 'c']

اگر عنصری که می‌خواهید در فهرست نباشد، ValueError می‌گیرید.

t.remove('d')
ValueError: list.remove(x): x not in list

۹.۶. فهرست‌ها و رشته‌ها

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

s = 'spam'
t = list(s)
t
['s', 'p', 'a', 'm']

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

s = 'resting by the quiet river'
t = s.split()
t
['resting', 'by', 'the', 'quiet', 'river']

یک آرگومان اختیاری به نام جداکننده (delimiter) مشخص می‌کند از کدام نویسه‌ها به‌عنوان مرز کلمه‌ها استفاده شود. مثال زیر از خط تیره به‌عنوان جداکننده استفاده می‌کند.

s = 'ex-student'
t = s.split('-')
t
['ex', 'student']

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

delimiter = ' '
t = ['resting', 'by', 'the', 'quiet', 'river']
s = delimiter.join(t)
s
'resting by the quiet river'

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

۹.۷. پیمایش یک فهرست

می‌توانید از دستور for برای پیمایش عنصرهای یک فهرست استفاده کنید.

for cheese in cheeses:
    print(cheese)
Cheddar
Edam
Gouda

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

s = 'resting by the quiet river'

for word in s.split():
    print(word)
resting
by
the
quiet
river

یک حلقه‌ی for روی فهرست تهی هرگز دستورهای تورفته را اجرا نمی‌کند.

for x in []:
    print('This never happens.')

۹.۸. مرتب‌سازی فهرست‌ها

پایتون تابع داخلی sorted را دارد که عنصرهای یک فهرست را مرتب می‌کند.

scramble = ['c', 'a', 'b']
sorted(scramble)
['a', 'b', 'c']

فهرست اصلی تغییر نمی‌کند.

scramble
['c', 'a', 'b']

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

sorted('letters')
['e', 'e', 'l', 'r', 's', 't', 't']

نتیجه یک فهرست است. برای تبدیل فهرست به رشته می‌توانیم از join استفاده کنیم.

''.join(sorted('letters'))
'eelrstt'

با رشته‌ی تهی به‌عنوان جداکننده، عنصرهای فهرست بدون هیچ چیز در میانشان به هم متصل می‌شوند.

۹.۹. شیءها و مقدارها

اگر این دستورهای نسبت‌دهی را اجرا کنیم:

a = 'banana'
b = 'banana'

می‌دانیم هر دوی a و b به یک رشته اشاره می‌کنند، اما نمی‌دانیم به رشته‌ی یکسان اشاره می‌کنند یا نه. دو وضعیت ممکن وجود دارد که در شکل زیر نشان داده شده‌اند.

(در کتاب اصلی اینجا نمودار رسم شده است: در نمودار سمت چپ، a و b هر کدام به یک رشته‌ی 'banana' جداگانه اشاره می‌کنند؛ در نمودار سمت راست، هر دو به یک رشته‌ی واحد اشاره می‌کنند.)

در نمودار سمت چپ، a و b به دو شیء متفاوت اشاره می‌کنند که مقدار یکسانی دارند. در نمودار سمت راست، به یک شیء اشاره می‌کنند. برای بررسی اینکه دو متغیر به یک شیء اشاره می‌کنند یا نه، می‌توانید از عملگر is استفاده کنید.

a = 'banana'
b = 'banana'
a is b
True

در این مثال پایتون فقط یک شیء رشته ساخت و هر دوی a و b به آن اشاره می‌کنند. اما وقتی دو فهرست می‌سازید، دو شیء دارید.

a = [1, 2, 3]
b = [1, 2, 3]
a is b
False

پس نمودار وضعیت این‌طور است.

(در کتاب اصلی اینجا نمودار رسم شده است: a و b هر کدام به یک فهرست جداگانه‌ی [1, 2, 3] اشاره می‌کنند.)

در این مورد می‌گوییم این دو فهرست هم‌ارز (equivalent) هستند، چون عنصرهای یکسانی دارند، اما یکسان (identical) نیستند، چون یک شیء نیستند. اگر دو شیء یکسان باشند، هم‌ارز هم هستند، اما اگر هم‌ارز باشند لزوماً یکسان نیستند.

۹.۱۰. هم‌نام‌سازی (aliasing)

اگر a به یک شیء اشاره کند و b = a را نسبت دهید، هر دو متغیر به یک شیء اشاره می‌کنند.

a = [1, 2, 3]
b = a
b is a
True

پس نمودار وضعیت این‌طور است.

(در کتاب اصلی اینجا نمودار رسم شده است: هر دوی a و b به یک فهرست [1, 2, 3] اشاره می‌کنند.)

ارتباط یک متغیر با یک شیء ارجاع (reference) نامیده می‌شود. در این مثال، دو ارجاع به یک شیء وجود دارد.

شیئی که بیش از یک ارجاع دارد بیش از یک نام دارد، پس می‌گوییم شیء هم‌نام (aliased) شده است. اگر شیء هم‌نام‌شده تغییرپذیر باشد، تغییراتی که با یک نام اعمال می‌شود بر نام دیگر هم اثر می‌گذارد. در این مثال، اگر شیئی را که b به آن اشاره می‌کند تغییر دهیم، شیئی را که a به آن اشاره می‌کند هم تغییر داده‌ایم.

b[0] = 5
a
[5, 2, 3]

پس می‌گوییم a این تغییر را «می‌بیند». اگرچه این رفتار می‌تواند مفید باشد، مستعد خطاست. به‌طور کلی، هنگام کار با شیءهای تغییرپذیر امن‌تر است که از هم‌نام‌سازی پرهیز کنید.

برای شیءهای تغییرناپذیر مثل رشته‌ها، هم‌نام‌سازی مشکل چندانی نیست. در این مثال:

a = 'banana'
b = 'banana'

تقریباً هیچ‌وقت فرقی نمی‌کند که a و b به یک رشته اشاره کنند یا نه.

۹.۱۱. آرگومان‌های فهرست

وقتی فهرستی را به یک تابع می‌دهید، تابع یک ارجاع به فهرست می‌گیرد. اگر تابع فهرست را تغییر دهد، فراخواننده تغییر را می‌بیند. برای مثال، pop_first از متد فهرست pop برای حذف اولین عنصر یک فهرست استفاده می‌کند.

def pop_first(lst):
    return lst.pop(0)

می‌توانیم آن را این‌طور به کار ببریم.

letters = ['a', 'b', 'c']
pop_first(letters)
'a'

مقدار بازگشتی اولین عنصر است که از فهرست حذف شده – همان‌طور که با نمایش فهرست تغییریافته می‌بینیم.

letters
['b', 'c']

در این مثال، پارامتر lst و متغیر letters نام‌های مستعار یک شیء‌اند، پس نمودار وضعیت این‌طور است:

(در کتاب اصلی اینجا نمودار رسم شده است: قاب __main__ با متغیر letters و قاب pop_first با پارامتر lst؛ هر دو به یک فهرست ['a', 'b', 'c'] اشاره می‌کنند.)

دادن ارجاع یک شیء به‌عنوان آرگومان تابع، نوعی هم‌نام‌سازی ایجاد می‌کند. اگر تابع شیء را تغییر دهد، این تغییرات بعد از پایان تابع هم باقی می‌مانند.

۹.۱۲. ساختن یک فهرست کلمه

در فصل قبل فایل words.txt را خواندیم و دنبال کلمه‌هایی با ویژگی‌های مشخص، مثل داشتن حرف e، گشتیم. اما کل فایل را چندین بار خواندیم که کارآمد نیست. بهتر است فایل را یک بار بخوانیم و کلمه‌ها را در یک فهرست بگذاریم. حلقه‌ی زیر نشان می‌دهد چگونه.

download('https://raw.githubusercontent.com/AllenDowney/ThinkPython/v3/words.txt');
word_list = []

for line in open('words.txt'):
    word = line.strip()
    word_list.append(word)
    
len(word_list)
113783

قبل از حلقه، word_list با یک فهرست تهی مقداردهی اولیه می‌شود. هر بار که حلقه تکرار می‌شود، متد append یک کلمه به انتها اضافه می‌کند. وقتی حلقه تمام می‌شود، بیش از ۱۱۳٬۰۰۰ کلمه در فهرست هست.

راه دیگر برای انجام همین کار استفاده از read برای خواندن کل فایل در یک رشته است.

string = open('words.txt').read()
len(string)
1016511

نتیجه یک رشته‌ی واحد با بیش از یک میلیون نویسه است. می‌توانیم با متد split آن را به فهرستی از کلمه‌ها بشکنیم.

word_list = string.split()
len(word_list)
113783

حالا برای بررسی اینکه یک رشته در فهرست هست یا نه، می‌توانیم از عملگر in استفاده کنیم. برای مثال، 'demotic' در فهرست هست.

'demotic' in word_list
True

اما 'contrafibularities' نیست.

'contrafibularities' in word_list
False

و باید بگویم، از این بابت «آناسپتیک» (anaspeptic) هستم. (این دو کلمه – مانند خود جمله – ساختگی‌اند؛ به بخش «از یک دستیار مجازی بپرسید» در تمرین‌ها نگاه کنید.)

۹.۱۳. اشکال‌زدایی

دقت کنید که بیشتر متدهای فهرست آرگومان را تغییر می‌دهند و None برمی‌گردانند. این برعکس متدهای رشته است که رشته‌ی جدیدی برمی‌گردانند و رشته‌ی اصلی را دست‌نخورده می‌گذارند.

اگر به نوشتن کد رشته‌ای مثل این عادت دارید:

word = 'plumage!'
word = word.strip('!')
word
'plumage'

وسوسه‌انگیز است که کد فهرست را این‌طور بنویسید:

t = [1, 2, 3]
t = t.remove(3)           # WRONG!

remove فهرست را تغییر می‌دهد و None برمی‌گرداند، پس عملیات بعدی که با t انجام می‌دهید احتمالاً شکست می‌خورد.

t.remove(2)
AttributeError: 'NoneType' object has no attribute 'remove'

این پیام خطا کمی توضیح لازم دارد. صفت (attribute) یک شیء، متغیر یا متدی است که به آن وابسته است. در این مورد، مقدار t برابر None است که یک شیء NoneType است و صفتی به نام remove ندارد، پس نتیجه AttributeError است.

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

۹.۱۴. واژه‌نامه

فهرست (list): شیئی که دنباله‌ای از مقدارها را در بر دارد.

عنصر (element): یکی از مقدارهای یک فهرست یا دنباله‌ی دیگر.

فهرست تودرتو (nested list): فهرستی که عنصر فهرست دیگری است.

جداکننده (delimiter): نویسه یا رشته‌ای که نشان می‌دهد رشته باید از کجا شکسته شود.

هم‌ارز (equivalent): داشتن مقدار یکسان.

یکسان (identical): یک شیء بودن (که هم‌ارزی را نتیجه می‌دهد).

ارجاع (reference): ارتباط بین یک متغیر و مقدارش.

هم‌نام‌شده (aliased): اگر بیش از یک متغیر به یک شیء اشاره کنند، شیء هم‌نام شده است.

صفت (attribute): یکی از مقدارهای نام‌دار وابسته به یک شیء.

۹.۱۵. تمرین‌ها

# This cell tells Jupyter to provide detailed debugging information
# when a runtime error occurs. Run it before working on the exercises.

%xmode Verbose

۹.۱۵.۱. از یک دستیار مجازی بپرسید

در این فصل من از کلمه‌های «contrafibularities» و «anaspeptic» استفاده کردم، اما این‌ها در واقع کلمه‌های انگلیسی نیستند. آن‌ها در برنامه‌ی تلویزیونی بریتانیایی Black Adder، فصل ۳، قسمت ۲، «Ink and Incapability» به کار رفته‌اند.

با این حال، وقتی از ChatGPT 3.5 (نسخه‌ی ۳ اوت ۲۰۲۳) پرسیدم این کلمه‌ها از کجا آمده‌اند، ابتدا ادعا کرد از Monty Python هستند و بعداً ادعا کرد از نمایشنامه‌ی Rosencrantz and Guildenstern Are Dead نوشته‌ی Tom Stoppard هستند.

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

اگر در هر یک از تمرین‌های این فصل گیر کردید، از یک دستیار مجازی کمک بگیرید. اگر نتیجه‌ای گرفتید که از امکاناتی استفاده می‌کند که هنوز یاد نگرفته‌ایم، می‌توانید به دستیار یک «نقش» (role) بدهید.

برای مثال، قبل از پرسیدن سؤال‌تان بنویسید «Role: Basic Python Programming Instructor» (نقش: مدرس مبانی برنامه‌نویسی پایتون). بعد از آن، پاسخ‌هایی که می‌گیرید باید فقط از امکانات پایه استفاده کنند. اگر باز هم امکاناتی دیدید که یاد نگرفته‌اید، می‌توانید بپرسید «Can you write that using only basic Python features?» (می‌توانی آن را فقط با امکانات پایه‌ی پایتون بنویسی؟)

۹.۱۵.۲. تمرین

دو کلمه آناگرام هستند اگر بتوانید حرف‌های یکی را جابه‌جا کنید تا دیگری ساخته شود. برای مثال، tops آناگرام stop است.

یک راه برای بررسی اینکه دو کلمه آناگرام هستند یا نه این است که حرف‌های هر دو کلمه را مرتب کنید. اگر فهرست‌های حرف‌های مرتب‌شده یکسان باشند، کلمه‌ها آناگرام‌اند.

تابعی به نام is_anagram بنویسید که دو رشته بگیرد و اگر آناگرام‌اند True برگرداند.

برای شروع، این یک طرح کلی از تابع با doctest است.

def is_anagram(word1, word2):
    """Checks whether two words are anagrams.
    
    >>> is_anagram('tops', 'stop')
    True
    >>> is_anagram('skate', 'takes')
    True
    >>> is_anagram('tops', 'takes')
    False
    >>> is_anagram('skate', 'stop')
    False
    """
    return None
# Solution goes here

می‌توانید از doctest برای آزمودن تابع‌تان استفاده کنید.

from doctest import run_docstring_examples

def run_doctests(func):
    run_docstring_examples(func, globals(), name=func.__name__)

run_doctests(is_anagram)

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

# Solution goes here

۹.۱۵.۳. تمرین

پایتون تابع داخلی reversed را دارد که دنباله‌ای از عنصرها – مثل فهرست یا رشته – را به‌عنوان آرگومان می‌گیرد و شیء reversed برمی‌گرداند که عنصرها را به ترتیب معکوس دارد.

reversed('parrot')
<reversed at 0x7f756aae1810>

(آدرس حافظه در خروجی در هر اجرا فرق می‌کند.)

اگر عنصرهای معکوس‌شده را در یک فهرست می‌خواهید، می‌توانید از تابع list استفاده کنید.

list(reversed('parrot'))
['t', 'o', 'r', 'r', 'a', 'p']

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

''.join(reversed('parrot'))
'torrap'

پس می‌توانیم تابعی که یک کلمه را معکوس می‌کند این‌طور بنویسیم.

def reverse_word(word):
    return ''.join(reversed(word))

کلمه‌ی متقارن (palindrome) کلمه‌ای است که از جلو و عقب یک‌جور نوشته می‌شود، مثل «noon» و «rotator». تابعی به نام is_palindrome بنویسید که آرگومان رشته‌ای بگیرد و اگر متقارن است True و در غیر این صورت False برگرداند.

این یک طرح کلی از تابع با doctest است که می‌توانید برای بررسی تابع‌تان به کار ببرید.

def is_palindrome(word):
    """Check if a word is a palindrome.
    
    >>> is_palindrome('bob')
    True
    >>> is_palindrome('alice')
    False
    >>> is_palindrome('a')
    True
    >>> is_palindrome('')
    True
    """
    return False
# Solution goes here
run_doctests(is_palindrome)

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

for word in word_list:
    if len(word) >= 7 and is_palindrome(word):
        print(word)

۹.۱۵.۴. تمرین

تابعی به نام reverse_sentence بنویسید که رشته‌ای را که هر تعداد کلمه با فاصله از هم جدا شده دارد به‌عنوان آرگومان بگیرد. باید رشته‌ی جدیدی برگرداند که همان کلمه‌ها را به ترتیب معکوس دارد. برای مثال، اگر آرگومان «Reverse this sentence» باشد، نتیجه باید «Sentence this reverse» باشد.

راهنمایی: می‌توانید از متد capitalize استفاده کنید تا کلمه‌ی اول با حرف بزرگ شروع شود و کلمه‌های دیگر به حروف کوچک تبدیل شوند.

برای شروع، این یک طرح کلی از تابع با doctest است.

def reverse_sentence(input_string):
    '''Reverse the words in a string and capitalize the first.
    
    >>> reverse_sentence('Reverse this sentence')
    'Sentence this reverse'

    >>> reverse_sentence('Python')
    'Python'

    >>> reverse_sentence('')
    ''

    >>> reverse_sentence('One for all and all for one')
    'One for all and all for one'
    '''
    return None
# Solution goes here
run_doctests(reverse_sentence)

۹.۱۵.۵. تمرین

تابعی به نام total_length بنویسید که فهرستی از رشته‌ها را بگیرد و مجموع طول رشته‌ها را برگرداند. مجموع طول کلمه‌های word_list باید $902{,}728$ باشد.

# Solution goes here
# Solution goes here