مبانی اولیه‌ی پایتون - رشته‌ها

Professional Python: Strings

09 اسفند 1399
درسنامه درس 3 از سری پایتون حرفه‌ای
Python حرفه ای: مبانی اولیه - رشته ها (قسمت 03)

تفاوت Expression و Statement

دو اصطلاح دیگر در زبان پایتون expression و statement هستند که در اکثر زبان های برنامه نویسی دیگر نیز وجود دارند. از آنجایی که هیچ ترجمه صحیح یا جا افتاده ای برای این دو کلمه در فارسی (ر حوزه برنامه نویسی) نداریم بهتر است عینا از همین کلمات استفاده کنید. برای درک بهتر تفاوت بین expression و statement به کد زیر نگاهی بیندازید:

height = 190

weight = height / 2

در کد بالا به قسمت height / 2 یک expression می گوییم چرا که یک مقدار را تولید خواهد کرد (۱۹۰ تقسیم بر ۲ می شود ۹۵). به عبارتی هر قسمت از کد که یک مقدار را تولید کند expression است. از طرف دیگر به کل خط دوم statement می گویند چرا که یک کار خاصی را انجام می دهد (مقداری را به متغیر weight منتسب می کند. با این حساب در کد بالا دو statement داریم:

height = 190

weight = height / 2

همچنین یک expression داریم:

height / 2

augmented assignment operator

اپراتور انتساب افزوده یا augmented assignment operator اپراتوری است که در زمینه خاصی از افزایش مقدار یک متغیر به ما کمک می کند اما قبل از توضیح دادن آن باید در مورد مبحث دیگری بحث کنیم. فرض کنید یک متغیر به شکل زیر داشته باشیم:

some_value = 5

حالا اگر بخواهیم مقدار آن را در همین کد ۲ عدد افزایش بدهیم می گوییم:

some_value = 5

some_value = 5 + 2

حالا some_value مقدار 7 را دارد. این کار انتساب مجدد است و قبلا در مورد آن صحبت کرده ایم. روش بهتر و پویا تر این است که از خود آن استفاده کنیم:

some_value = 5

some_value = some_value + 2

در این کد گفته ایم some_value برابر است با مقدار خودش (some_value که ۵ است) به علاوه ۲! به همین سادگی از خود متغیر برای انتساب مقدار جدید به آن استفاده کرده ایم اما اپراتور خاصی به نام اپراتور انتساب افزوده وجود دارد و همانطور که از نامش پیدا است یک متغیر را افزایش می دهد. این اپراتور به جای استفاده از علامت = از علامت =+ استفاده می کند:

some_value = 5

some_value += 2

استفاده از =+ یعنی مقدار فعلی را گرفته و به تعداد واحدهای سمت راست علامت = به آن اضافه کن بنابراین some_value در کد بالا باز هم برابر ۷ خواهد بود. ما در اینجا نگفته ایم که some_value برابر ۲ است بلکه گفته ایم باید ۲ واحد افزایش پیدا کند. شما می توانید این کار را برای حالت برعکس (کاهشی) نیز انجام بدهید:

some_value = 5

some_value -= 2

با انجام این کار some_value برابر ۳ خواهد بود چرا که ۲ واحد را از آن کم کرده ایم. یادتان باشد که این اپراتور متغیر جدیدی نمی سازد بنابراین اگر فقط کد زیر را بنویسید به خطا برمی خورید:

some_value -= 2

ما در این کد گفته ایم some_value دو واحد کاهش پیدا کند اما اصلا متغیری به نام some_value وجود ندارد بنابراین با اجرا کردن این کد به خطا برخورد می کنید.

همچنین می توانیم از این اپراتور برای ضرب مقادیر استفاده کنیم:

some_value = 5

some_value *= 2

some_value در کد بالا برابر ۱۰ است چرا که مقدار قبلی آن را در ۲ ضرب کرده ایم. آخرین عملیات ریاضی برای این اپراتور نیز تقسیم است بنابراین:

some_value = 10

some_value /= 5

آشنایی با رشته ها (String)

تا این قسمت با نوع داده های int (عدد صحیح) و float (عدد اعشاری) آشنا شدیم و در این قسمت نوبت به نوع داده یا data type سوم می رسد که string (رشته) است. رشته ها به سادگی مجموعه ای از کاراکترها هستند، نه بیشتر و نه کمتر! برای تعریف رشته ها در پایتون از علامت single quotation یا double quotation استفاده می کنیم:

علائم نگارشی برنامه نویسی
علائم نگارشی برنامه نویسی

به مثال زیر توجه کنید:

my_name = "Amir"

ما در اینجا متغیری به نام my_name را داریم که یک رشته با مقدار Amir را در خود دارد، به همین سادگی! همانطور که گفتم به جای double quotation می توانیم از single quotation نیز استفاده کنیم و نتیجه یکی است:

my_name = 'Amir'

شکستن رشته ها در پایتون

این روش برای تعریف رشته ها در پایتون رایج ترین روش است اما در برخی از اوقات نیاز به نوشتن رشته های چند خطی داریم. در این شرایط چه کار می توان کرد؟ شما به صورت پیش فرض اجازه ندارید رشته ها را با کلید enter بشکنید و به خط بعدی بروید اما دو راه حل وجود دارد. راه حل اول استفاده از \ است. مثال:

my_name = "My Name is Amir \and I am 25" print(my_name)

در صورتی که \ را نگذارید با خطا روبرو می شوید. نتیجه اجرای کد بالا رشته زیر خواهد بود:

My Name is Amir and I am 25

همانطور که می بینید کد به درستی کار می کند اما قسمت شکسته شدن خط را رعایت نکرده است. در صورتی که می خواهید حتما قسمت شکستگی خط را نیز رعایت کنید باید از روش خاصی استفاده کنید که راه حل دوم ما است؛ استفاده از سه علامت single quotation پشت سر هم:

my_name = '''My Name is Amir

and I am 25'''




print(my_name)

با اجرای کد بالا نتیجه زیر را دریافت می کنید:

My Name is Amir

and I am 25

بنابراین شکستگی خط نیز رعایت شده است.

چسباندن رشته ها در پایتون

نکته جالب دیگر اینجاست که ما می توانیم عملیات های مختلفی را روی این رشته ها انجام بدهیم. به طور مثال ما اگر نام کوچک و نام خانوادگی یک فرد را داشته باشیم می توانیم آن ها را با اپراتور + به هم بچسبانیم:

first_name = "Amir"

last_name = "Zouerami"




full_name = first_name + last_name;




print(full_name)

با اجرای کد بالا عبارت AmirZouerami را دریافت می کنیم اما چرا نام و نام خانوادگی به هم چسبیده است؟ اگر یادتان باشد توضیح دادم که رشته ها فقط مجموعه ای از کاراکترها هستند و کامپیوتر زبان ما انسان ها را نمی فهمد، بنابراین نمی تواند خودش تشخیص بدهد که نام و نام خانوادگی را از هم جدا کند. برای حل این مشکل چند روش مختلف داریم؛ روش اول این است که در رشته first_name یا last_name یک اسپیس اضافه کنیم. به طور مثال:

first_name = "Amir "

last_name = "Zouerami"




full_name = first_name + last_name;




print(full_name)

من در اینجا بعد از Amir یک اسپیس را اضافه کرده ام. همچنین می توانیم این اسپیس را قبل از نام خانوادگی اضافه کنیم:

first_name = "Amir"

last_name = " Zouerami "




full_name = first_name + last_name;




print(full_name)

در هر صورت کدها درست کار می کنند اما روش بهتر این است که یک رشته خالی را در هنگام محاسبه full_name اضافه کنیم:

first_name = "Amir"

last_name = " Zouerami"




full_name = first_name + " " + last_name;




print(full_name)

با اجرای این کد عبارت Amir  Zouerami برای ما نمایش داده می شود. اگر یادتان باشد علامت + در اعداد باعث جمع شدن آن ها می شد اما طبیعتا نمی توانیم رشته ها را به صورت ریاضی جمع کنیم بنابراین + در رشته ها در پایتون باعث به هم چسبانده شدنشان می شود. در انگلیسی به این عملیات string concatenation می گویند. حالا یک معمای جالب برایتان دارم؛ اگر یک رشته را با یک عدد جمع کنیم چه می شود!؟

some_value = "Amir" + 13

print(some_value)

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

Traceback (most recent call last):

  File "main.py", line 1, in <module>

    some_value = "Amir" + 13

TypeError: can only concatenate str (not "int") to str

در اینجا یک خطا دریافت کرده ایم که می گوید اجازه جمع زدن رشته و عدد را نداریم که طبیعی است. از نظر ریاضی نمی توانیم یک عدد را با یک رشته جمع بزنیم، چنین مفهومی اصلا معنی ندارد! بیایید عدد ۱۳ را به یک رشته تبدیل کنیم:

some_value = "Amir" + "13"

print(some_value)

با اجرای کد بالا نتیجه Amir13 را می گیریم که طبیعی است. البته روش دیگری برای تبدیل یک عدد به رشته نیز وجود دارد. اگر یادتان باشد نوع داده رشته یا string در زبان پایتون با str مشخص می شد اما ما می توانیم از آن به عنوان یک تابع نیز استفاده کنیم:

some_value = "Amir" + str(13)

print(some_value)

با اجرای این کد باز هم Amir13 را می گیریم. برای تبدیل انواع مختلف داده به هم می توانید از این روش استفاده کنید. مثلا برای تبدیل به عدد اعشاری از ()float و برای تبدیل به عدد صحیح از ()int استفاده می کنیم:

some_number = int("13")

some_string = str(13)

some_float = float(13)

some_float = float("13")




print(some_number)

print(some_string)

print(some_float)

print(some_float)

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

13

13

13.0

13.0

از آنجایی که این مثال بسیار واضح است توضیح بیشتری نمی دهم. در نهایت باید به یاد داشته باشید که "۱۳" یک رشته است و عدد نیست بنابراین اگر "۱۳" را با "۱۳" جمع بزنید عدد ۲۶ را دریافت نمی کنید:

first_number = "13"

second_number = "13"




print(first_number + second_number)

ما در کد بالا دو رشته ۱۳ را با هم جمع کرده ایم و سپس نتیجه را چاپ می کنیم. نتیجه چاپ شده باید ۱۳۱۳ باشد! چرا؟ به دلیل اینکه ۱۳ یک رشته است و با آن دقیقا مانند یک رشته برخورد می شود. همانطور که Amir + Zouerami برابر AmirZouerami شده بود "۱۳" + "۱۳" نیز برابر "۱۳۱۳" خواهد شد نه ۲۶! یادتان باشد که عملیات جمع ریاضی با string concatenation یکی نیست.

escape کردن رشته ها در پایتون

escape کردن یا فراری دادن رشته ها در پایتون یکی از مفاهیم مهم در کار با رشته ها است. فرض کنید رشته ای به شکل I'm Amir داشته باشیم و بخواهیم آن را در یک متغیر قرار بدهیم:

name = 'I'm Amir'

print(name)

همانطور که می بینید در این حالت سه single quote داریم و این باعث ایجاد خطا در کد ما می شود. از نظر پایتون برای تعریف رشته یک جفت single quote یا double quote خواهیم داشت و بر همین اساس می توانیم با روش زیر مشکل این کد را حل کنیم:

name = "I'm Amir"

print(name)

این بار هیچ خطایی نمی گیریم چرا که علامت ' درون رشته با علامت " که مشخص کننده ابتدا و انتهای رشته است متفاوت هستند. حالت برعکس این مسئله نیز صادق است، یعنی کد زیر به ما خطا می دهد:

name = 'He said "NO!"'

print(name)

این کد نیز هیچ مشکلی ندارد چرا که برای مشخص کردن انتهای و ابتدای رشته از single quote استفاده کرده ایم در حالی که برای نقل قول داخل رشته از double quote استفاده کرده ایم. کد بالا عبارت "!He said "NO را برایمان نمایش می دهد که صحیح است. مسئله اینجاست که اگر بخواهیم از هر دو استفاده کنیم چطور؟ در چنین حالتی باید آن کاراکترهای خاص را escape کنیم (فراری بدهیم) تا پایتون آن ها را به عنوان کاراکتر خاص نبیند بلکه به عنوان جزئی از رشته به آن ها نگاه کنید. عملیات escape کردن همیشه با علامت \ انجام می شود:

name = 'I\'m Amir'

print(name)

اولین کاراکتر بعد از \ به عنوان یک رشته عادی در نظر گرفته می شود نه یک کاراکتر خاص بنابراین در کد بالا ' یک کاراکتر ساده خواهد بود چرا که قبل از آن \ را داریم. در مثال اول این بخش، این کد به ما خطا می داد اما حالا بدون خطا اجرا شده و عبارت I'm Amir را نمایش می دهد!

مبحث دیگری که به مبحث escaping نزدیک است، کاراکترهای ویژه ای هستند که با \ اضافه می شوند. در صورتی که \ را به برخی از کاراکترهای عادی اضافه کنید که نیازی به escape شدن نداشته باشد، یک کاراکتر ویژه را خلق کرده اید. به طور مثال t یک کاراکتر عادی است اما اگر t\ را در یک رشته بنویسید، یک کاراکتر tab را خواهیم داشت. مثال:

some_value = '\t this is a special character'

print(some_value)

با اجرای این کد رشته زیر را دریافت می کنید:

     this is a special character

به فاصله قبل از کلمه this دقت کنید. این فاصله یک کاراکتر tab است (فشردن کلید tab روی کیبورد خودتان). کاراکتر خاص بعدی n\ است که همان کار کلید enter را انجام می دهد یعنی به خط بعدی می رود:

some_value = 'Hello, \n Have a good day!'

print(some_value)

نتیجه اجرای کد بالا مقدار زیر خواهد بود:

Hello,

 Have a good day!

آشنایی با formatted strings

در برخی از اوقات نیاز به ترکیب تعداد زیادی از متغیر ها در یک یک رشته را داریم. ما قبلا یاد گرفتیم که می توانیم با استفاده از string concatenation دو رشته را به هم بچسبانیم بنابراین برای چسباندن یک متغیر (حاوی رشته) و یک رشته دیگر به شکل زیر عمل می کردیم:

name = "Amir"




print('hello ' + name)

با اجرای این کد مقدار hello Amir را دریافت می کنیم که طبیعی است اما اگر بخواهیم سن کاربر را نیز اضافه کنیم چطور؟

name = "Amir"

age = 25




print('hello ' + name + '. You are ' + age + ' years old.')

در چنین حالتی یک مشکل به وجود می آید. در واقع با اجرای این کد خطای زیر را می گیرید:

Traceback (most recent call last):

  File "main.py", line 4, in <module>

    print('hello ' + name + '. You are' + age + 'years old.')

TypeError: can only concatenate str (not "int") to str

مشکل اینجاست که ما یک عدد صحیح (int) را با یک رشته (str) جمع کرده ایم! راه حل مبتدی و ساده تر این است که ابتدا این عدد را نیز به یک رشته تبدیل کنیم:

name = "Amir"

age = 25




print('hello ' + name + '. You are ' + str(age) + ' years old.')

با اجرای این کد نتیجه زیر را می گیرید که صحیح است:

hello Amir. You are 25 years old.

همانطور که می بینید ما برای ساخت یک رشته ساده شروع به استفاده از انواع و اقسام توابع می کنیم و اگر همینطور پیش برویم فایل ما شلوغ خواهد شد. راه حل بهتر استفاده از مفهوم formatted strings است. برای انجام این کار باید یک حرف f را به ابتدای رشته خود بچسبانید:

name = "Amir"

age = 25




print(f'Hello {name}. You are {age} years old.')

همانطور که می بینید من یک f را به رشته خودم چسبانده ام که به پایتون می گوید رشته قرار است formatted باشد (دارای فرمت یا قالب است) و سپس برای نمایش متغیر ها از علامت {} (در انگلیسی curly braces یا curly brackets خوانده می شوند) استفاده می کنیم. همانطور که می بینید این کد هم از نظر خوانش و هم از نظر تعداد دستورات بسیار ساده تر است. با اجرای این کد باز هم نتیجه زیر را می گیریم:

Hello Amir. You are 25 years old.

در ضمن حتما متوجه شده اید که تغییر age از عدد صحیح به رشته نیز به صورت خودکار انجام شده است. این قابلیت یکی از قابلیت های پایتون ۳ است اما در پایتون ۲ روش دیگری داشتیم. اگر بخواهم کد بالا را در پایتون ۲ بنویسم می گویم:

name = "Amir"

age = 25




print('Hello {}. You are {} years old.'.format(name, age))

به عبارتی باید تابعی به نام format را روی رشته خودتان صدا می زدید و سپس مشخص می کردید که چه مقادیری به ترتیب درون علامت های {} قرار بگیرند. این کد باز هم همان نتیجه قبلی را تولید می کند اما بر اساس نسخه دوم پایتون نوشته شده است.

index رشته ها در پایتون

ایندکس یا اندیس یا index یک مفهوم بسیار مهم و پرکاربرد در برنامه نویسی است. اگر یادتان باشد گفته بودیم که هر رشته مجموعه ای از کاراکترها است اما باید بدانید که این کاراکترها ترتیب دارند. به طور مثال رشته Amir دارای چهار حرف است که هر کدام ترتیب جایگاه خودشان را دارند:

Amir

0123

من هر حرف را به یک شماره اختصاص داده ام. در علوم کامپیوتر شمارش تقریبا همیشه از صفر شروع می شود بنابراین حرف شماره صفر A می باشد، حرف شماره یک m می باشد،حرف شماره دو i و حرف شماره سه r می باشد. به هر کدام از این اعداد یک ایندکس می گوییم بنابراین در رشته بالا ایندکسِ صفر برابر A است و الی آخر. چرا چنین چیزی اهمیت دارد؟ به دلیل اینکه ما می توانیم قسمت های خاصی از یک رشته را با این شماره گذاری دریافت کنیم. به مثال زیر توجه کنید:

my_string = "This is a great day!"




first_letter = my_string[0]




print(first_letter)

ما برای دسترسی به یک ایندکس خاص باید از علامت های [] یا براکت (square brackets) استفاده کرده و شماره آن ایندکس را پاس بدهیم. من در اینجا به دنبال ایندکس صفر هستم (اولین حرف از رشته بالا) بنابراین آن را در یک متغیر جدید ذخیره کرده و سپس چاپ کرده ام. با اجرای این کد نتیجه زیر را دریافت می کنیم:

T

به همین سادگی اولین حرف رشته my_string را به دست آورده ایم. توجه کنید که تمام کاراکترها در این رشته یک ایندکس خاص دارند؛ به طور مثال اسپیس یا فضای خالی بین this و is خودش یک کاراکتر مستقل است دسترسی به ایندکس چهار ([4]my_string) یک اسپیس خالی را برایمان برمی گرداند. این مسئله برای علامت تعجب و هر کاراکتر دیگری نیز صحیح است.

در ضمن شما می توانید به جای دریافت یک ایندکس خاص، مجموعه ای از ایندکس ها را دریافت کنید. برای انجام این کار به جای یک عدد (ایندکس) دو عدد (ایندکس آغازین و پایانی) را پاس داده و آن ها را با علامت : از هم جدا می کنیم. به طور مثال من می خواهم قسمتی از کلمه اول را دریافت کنم بنابراین:

my_string = "This is a great day!"




first_letter = my_string[0:3]




print(first_letter)

با اجرای این کد، thi را دریافت می کنیم. چرا؟ به دلیل اینکه this به شکل زیر ایندکس بندی شده است:

  • ایندکس T برابر صفر
  • ایندکس h برابر یک
  • ایندکس i برابر دو
  • ایندکس s برابر سه

ما در کد بالا گفته ایم که از صفر شروع کن و زمانی که به ایندکس سوم رسیدی کار تمام شده است به همین دلیل ایندکس سوم (حرف s) را دریافت نکرده ایم. البته اگر عدد دوم را مشخص نکنید، تا انتهای رشته برایتان برگردانده می شود:

my_string = "This is a great day!"




first_letter = my_string[1:]




print(first_letter)

اگر کد بالا را اجرا کنید نتیجه !his is a great day را می گیرید (حرف T را نداریم چرا که از ایندکس یک شروع کرده ایم نه صفر). طبیعتا می توانیم این کار را از طرف دیگر نیز انجام بدهیم:

my_string = "This is a great day!"




first_letter = my_string[:4]




print(first_letter)

ما نقطه آغازین را مشخص نکرده ایم بنابراین از همان ابتدا (ایندکس صفر) شرع می کنیم و تا ایندکس ۴ پیش می رویم. نتیجه اجرای این کد کلمه This خواهد بود. ما حتی می توانیم کار را پیشرفته تر کنیم و مقدار سومی را نیز به براکت ها پاس بدهیم! به این مقدار سوم stepover می گویند که مشخص می کند شمارش چند تا چند تا باشد. به مثال زیر توجه کنید:

my_string = "This is a great day!"




first_letter = my_string[0:8:2]




print(first_letter)

مقدار پیش فرض برای stepover عدد ۱ است چرا که تک تک کاراکترها را برمی گرداند اما من در کد بالا این مقدار را روی ۲ گذاشته ام. نتیجه این کد رشته "Ti s" خواهد بود. چطور؟ ما از صفر شروع می کنیم که حرف T است و سپس h را نادیده می گیریم، سپس i را گرفته و s را نادیده می گیریم، سپس اسپیس (فضای خالی) را گرفته و i را نادیده می گیریم و در نهایت s را دریافت می کنیم. برای درک راحت تر می گوییم: حرف اول را بگیر، حرف دوم را رها کن، حرف بعدی را بگیر، حرف بعدی اش را ها کن و الی آخر. طبیعتا ترفند های بخش قبل در این قسمت نیز انجام می شوند:

my_string = "This is a great day!"




first_letter = my_string[::2]




print(first_letter)

به نظر شما اگر این کد را اجرا کنیم چه می شود؟ ما در این کد ابتدا و انتها را مشخص نکرده ایم بنابراین از اول تا آخر رشته را شامل می شود اما گفته ایم که stepover روی ۲ باشد بنابراین رشته زیر را دریافت می کنیم:

Ti sagetdy

T را گرفته ایم و h را رها کرده ایم، i را گرفته ایم و s را رها کرده ایم، اسپیس را گرفته این و i را رها کرده ایم و الی آخر. مسئله بعدی این است که اگر ایندکس را به صورت منفی پاس بدهیم چه می شود؟ مثلا:

my_string = "This is a great day!"




first_letter = my_string[-1]




print(first_letter)

زمانی که ایندکس را به صورت منفی پاس بدهید، شمارش از انتهای رشته آغاز می شود بنابراین کد بالا علامت تعجب را به ما برمی گرداند. توجه داشته باشید که شمارش در این حالت به جای صفر از یک آغاز می شود. چرا؟ به دلیل اینکه منفی صفر (0-) وجود ندارد بنابراین باید از یک شروع کنیم. بر اساس همین ترفندی که به شما یاد داده ام باید بتوانید یک رشته را برعکس کنید! به طور مثال:

my_string = "This is a great day!"




first_letter = my_string[::-1]




print(first_letter)

ما در این کد ابتدا و انتها تعیین نکرده ایم اما stepover را روی ۱- گذاشته ایم بنابراین نتیجه این کد رشته زیر خواهد بود:

!yad taerg a si sihT

در ضمن هیچ تفاوتی بین حروف فارسی و انگلیسی نیست:

my_string = "به آکادمی روکسو خوش آمدید"




first_letter = my_string[::-1]




print(first_letter)

نتیجه:

دیدمآ شوخ وسکور یمداکآ هب

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

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری پایتون حرفه‌ای توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.