رشته‌ها

پیمایش رشته و متدهای پرکاربرد: in، lower، strip و isdigit

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

در درس قبل با اندیس و برش آشنا شدیم. حالا سراغ کارهای روزمره با متن می‌رویم: گشتن روی کاراکترها، جست‌وجو، تمیز کردن و تبدیل.

این درس از حلقهٔ for استفاده می‌کند. اگر هنوز آن را نخوانده‌اید، اول نگاهی به آن بیندازید.

پیمایش کاراکترها

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

s = "salam"

# روش ۱: با اندیس
for i in range(len(s)):
    print(i, s[i])
s = "salam"

# روش ۲: مستقیم روی خود رشته (پایتونی‌تر)
for ch in s:
    print(ch)

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

⚠️ اشتباه رایج: for ch in range(s). range فقط عدد می‌گیرد. روی رشته مستقیم بنویسید for ch in s.

عملگر in

in می‌پرسد «آیا این تکه داخل آن رشته هست؟» و جوابش True یا False است:

print("a" in "salam")      # True
print("lam" in "salam")    # True
print("x" in "salam")      # False
print("," in "ali,30")     # True

not in هم برعکسش است: "x" not in "salam" می‌شود True.

مثال: شمارش حروف صدادار

برنامه‌ای بنویسید که یک متن انگلیسی بگیرد و بگوید چند حرف صدادار (a، e، i، o، u) دارد.

نسخهٔ اول

count = 0
text = input("yechi benevis: ")
for ch in text:
    if ch == 'a' or ch == 'e' or ch == 'i' or ch == 'o' or ch == 'u':
        count += 1
print(count)

⚠️ یک اشتباه بسیار رایج این است که بنویسید if ch == 'a' or 'e' or 'i':. این همیشه True است! چون 'e' به‌تنهایی یک رشتهٔ غیرخالی است و ارزش منطقی‌اش True است. هر طرف or باید یک مقایسهٔ کامل باشد.

این کد با salam جواب درست (۲) می‌دهد، ولی با SALAM جواب ۰ می‌دهد، چون 'A' و 'a' دو کاراکتر متفاوت‌اند.

نسخهٔ بهتر: lower و in

count = 0
text = input("yechi benevis: ")
for ch in text.lower():
    if ch in "aeiou":
        count += 1
print(count)

دو بهبود: text.lower() همه‌چیز را کوچک می‌کند، و ch in "aeiou" جای آن orهای طولانی را می‌گیرد.

متدهای پرکاربرد رشته

متد تابعی است که به یک شیء چسبیده و با نقطه صدا زده می‌شود: text.lower(). چون رشته‌ها تغییرناپذیرند، این متدها رشتهٔ اصلی را عوض نمی‌کنند؛ یک رشتهٔ جدید برمی‌گردانند.

s = "   Hello World  \n"
print(repr(s.strip()))          # 'Hello World'  ← حذف فاصله و \n از دو طرف
print(s.strip().lower())        # hello world
print(s.strip().upper())        # HELLO WORLD
print(s.strip().replace("World", "Python"))
print(s.count("l"))             # 3
print(s.strip().startswith("He"))
print("  salam   ".strip() == "salam")
متد کار
lower() / upper() همه کوچک / همه بزرگ
strip() حذف فاصله، تب و \n از ابتدا و انتها
replace(a, b) جایگزینی همهٔ aها با b
count(x) تعداد تکرار x
startswith(x) / endswith(x) با x شروع/تمام می‌شود؟
find(x) اندیس اولین x (یا -1 اگر نبود)
isdigit() همهٔ کاراکترها رقم‌اند؟

💡 strip() هنگام خواندن فایل و گرفتن ورودی کاربر نجات‌دهنده است: فاصله‌های اضافه و کاراکتر \n آخر خط را پاک می‌کند.

💡 برای دیدن همهٔ متدهای رشته در Jupyter، بنویسید s. و کلید Tab را بزنید.

مثال: ورودی عدد است یا نه؟

قبل از اینکه ورودی را با int() تبدیل کنیم، بهتر است مطمئن شویم واقعاً عدد است. با حلقه:

inp = input("Vorudi vared kon: ")
non_digits = 0
for ch in inp:
    if ch not in "0123456789":
        non_digits += 1

if non_digits == 0:
    print("It's numeric:", int(inp))
else:
    print("It's not a numeric!")

پایتون برای این کار یک متد آماده هم دارد:

inp = input("Vorudi vared kon: ")
if inp.isdigit():
    print("It's numeric:", int(inp))
else:
    print("It's not a numeric!")

⚠️ isdigit() برای اعداد منفی ("-5") و اعشاری ("3.5") False برمی‌گرداند. راه کلی‌تر استفاده از try/except است.

رشته‌های چندخطی

با سه کوتیشن (""" یا ''') می‌شود رشته‌ای نوشت که چند خط دارد؛ Enterها هم جزو رشته می‌شوند:

poem = """Line one
Line two
Line three"""
print(poem)
print(len(poem.split("\n")), "lines")

همین شکل برای نوشتن docstring توابع هم استفاده می‌شود.

تمرین

برنامه‌ای بنویسید که یک کلمه بگیرد و بگوید چند حرف بی‌صدا (غیر از aeiou) دارد. حروف بزرگ و کوچک فرقی نکنند و فاصله‌ها شمرده نشوند.

یک جواب
text = input("کلمه: ")
count = 0
for ch in text.lower():
    if ch.isalpha() and ch not in "aeiou":
        count += 1
print(count)

isalpha() می‌گوید کاراکتر یک حرف الفبا هست یا نه، پس فاصله و رقم و علامت شمرده نمی‌شوند.