وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

بررسی کنید که آیا رشته حاوی عدد در پایتون است یا خیر

0 110
زمان لازم برای مطالعه: 7 دقیقه


معرفی

این که آیا در حال ساخت یک اسکریپت تأیید برای ورودی کاربر هستید، یک فرم ورود به سیستم که از کاربران می‌خواهد یک کاراکتر را در یک رمز عبور وارد کنند – بررسی اینکه آیا یک رشته دارای یک کاراکتر است یا نه، عملیات غیر معمولی نیست.

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

بررسی کنید که آیا رشته حاوی عدد در پایتون است یا خیر

راه های متعددی برای بررسی اینکه آیا a شخصیت یک عدد است (ord()، isnumeric()، isdigit()) که می توانید با یک حلقه for جفت کنید تا حداقل یک ضربه مثبت را بررسی کنید. از طرف دیگر، می‌توانید از عبارات با قاعده به عنوان تطبیق‌کننده‌های الگوی عمومی استفاده کنید، که انعطاف‌پذیر، قدرتمند و برای اعمال بر روی مجموعه‌های بزرگ متن طراحی شده‌اند. در نهایت – شما همیشه می توانید map() به هر کاراکتر یک عبارت شرطی داده می شود و برمی گردد True است any() از آنها منجر می شود True.

انتخاب بین اینها باید کارایی روشها، پرحرفی و سبک کدگذاری و همچنین وظایف بالادستی یا پایین دستی مرتبط با عملیات را در نظر بگیرد.

بررسی کنید آیا رشته حاوی عدد با ord() است یا خیر

را ord() تابع یک کاراکتر می گیرد و آن را برمی گرداند ASCII ارزش:

print(ord('0')) 
print(ord('9')) 

مقدار ASCII از 0 48 است و مقدار ASCII از 9 57 است. هر عددی بین اینها، با بسط، دارای مقدار ASCII بین 48 و 57. حال برای بررسی اینکه آیا رشته عددی دارد یا خیر، کل رشته ورودی را پیمایش می کنیم و مقدار اسکی هر کاراکتر را بررسی می کنیم، اگر مقدار اسکی بیشتر از 47 و کمتر از 58 باشد، به این معنی است که یک عدد است و برمی گردیم. True:

input_string = "My name is Satyam & I am 22 yrs old"
flag = False
for ch in input_string:
    ascii_code = ord(ch)
    if 47 < ascii_code < 58:
        flag = True
        break
if flag:
    print("Yes, the string contains a number.")
else:
    print("No, the string does not contain a number.")

این نتیجه در:

Yes, the string contains a number.

بررسی کنید که آیا رشته حاوی عدد با () isnumeric است

را isnumeric() تابع برمی گردد True اگر رشته ورودی فقط شامل اعداد باشد، در غیر این صورت، باز می گردد False:

str1 = "918"
print("String is whole numeric?", str1.isnumeric())
str2 = "The meaning of the universe is 42"
print("String is whole numeric?", str2.isnumeric())

این نتیجه در:

String is whole numeric? True 
String is whole numeric? False

توجه داشته باشید: را isnumeric() عملکرد آنطور که انتظار دارید رفتار نخواهد کرد اعداد منفی یا شناور. اگر رشته ای را فقط با اعداد منفی یا شناور پاس کنیم، برمی گردد False، زیرا - و . کاراکترهای مرتبط با اعداد منفی و شناورها در واقع اعداد نیستند.

str1 = "-918"
print("String is whole numeric?", str1.isnumeric()) 

str2 = "91.8"
print("String is whole numeric?", str2.isnumeric()) 

اگرچه، از آنجایی که کاراکترها فقط رشته هایی به طول 1 در پایتون هستند – می توانید از طریق کاراکترها تکرار کنید و استفاده کنید isnumeric() برای بررسی اینکه آیا آنها یک عدد هستند:

input_string = "My name is Satyam & I am 22 yrs old"
flag = False
for ch in input_string:
    if ch.isnumeric():
        flag = True
        break
if flag:
    print("Yes, the string contains a number.")
else:
    print("No, the string does not contain a number.")

بررسی کنید آیا رشته حاوی عدد با isdigit() است

را isdigit() تابع بررسی می کند که آیا تمام کاراکترهای یک رشته رقمی هستند یا خیر. اگر بله – برمی گردد Trueو اگر نه، برمی گردد False. باز هم، از آنجایی که کاراکترها فقط رشته هایی به طول 1 در پایتون هستند – این روش را می توان در یک حلقه برای هر کاراکتر استفاده کرد:

input_string = "My name is Satyam & I am 22 yrs old"
flag = False
for ch in input_string:
    if ch.isdigit():
        flag = True
        break
if flag:
    print("Yes, the string contains a number.")
else:
    print("No, the string does not contain a number.")

توجه داشته باشید: را isdigit() روش فقط به همان شیوه عمل می کند isnumeric()و اگر رشته ای حاوی شناور یا عدد منفی را به آن پاس دهید، False به دلیل اعداد نبودن کاراکترهای خاص برگردانده می شود. هر چند در سطح شخصیت، اگر تا زمانی که یکی باشد True مقدار برای تعیین اینکه آیا رشته دارای یک عدد است یا خیر کافی است – قابل اجرا است.

پیشنهاد می‌کنیم بخوانید:  روش تقسیم رشته روی جداکننده های متعدد در پایتون

تفاوت بین isnumeric() و isdigit()؟

بنابراین، چه تفاوتی بین آنها وجود دارد isnumeric() و isdigit()? در حالی که ما در آن هستیم – چه خبر؟ isdecimal()?

  • isnumeric() بررسی می کند که آیا هر کاراکتری a است یا خیر نمایندگی یونیکد از یک مقدار عددی (که شامل نمایش های عددی رومی، بالانویس ها، زیرنویس ها و کسرها می شود)
  • isdigit() بررسی می کند که آیا هر کاراکتری a است یا خیر رقم یونیکد (که شامل نمایش های عددی رومی نمی شود، اما شامل super/subscripts و کسری می شود)
  • isdecimal() بررسی می کند که آیا هر یک از کاراکترها a است رقم اعشاری (که برمی گردد False برای هر چیزی که نیست 0..9 در پایه 10)

isnumeric() گسترده ترین روش است، در حالی که isdecimal() باریک ترین بین این سه است.

بررسی کنید که آیا رشته حاوی عدد با map() و any() است یا خیر

را map() تابع تابع ارائه شده را برای هر عنصر تکرار پذیر ارسال شده در تابع نقشه اجرا می کند. هر عنصر یک تکرارپذیر به عنوان یک پارامتر به تابع ارسال می شود:

map(function, iterable)

را function برای هر آیتم از اجرا می شود iterable. این اجازه می دهد تا برای منطق بسیار انعطاف پذیر و قدرتمند، تنها محدود به وسعت از function شما تماس بگیرید روی ورودی! متد a را برمی گرداند map به عنوان مثال، که می تواند به راحتی به مجموعه های دیگر مانند یک لیست یا مجموعه تبدیل شود.

ما می‌توانیم تابعی بنویسیم که یک عدد بولی نشان دهد که آیا یک کاراکتر یک عدد است یا خیر map() بنابراین فراخوانی به لیستی از مقادیر بولی منجر می شود.

را any() برمی گرداند True اگر هر عنصری از تکرار پذیرفته شده باشد True، در غیر این صورت باز می گردد False.

این دو را با هم رشته کنیم – می توانیم یک اسکریپت کوتاه و سطح بالا ایجاد کنیم و حلقه for را انتزاع کنیم:

def func(ch):
    return ch.isdigit() 

input_string = "My name is Satyam & I am 22 yrs old"
contains_number = any(list(map(func, input_string)))
print("Is there a number present?", contains_number)

این نتیجه در:

Is there a number present? True

اگر تابع شما یک خط است – نیازی به استخراج آن به عنوان یک تابع نامگذاری شده نیست. می توانید یک ناشناس بنویسید تابع لامبدا در عوض برای اختصار:

input_string = "My name is Satyam & I am 22 yrs old"
contains_number = any(list(map(lambda ch: ch.isdigit(), input_string)))
print("Is there any number present?", contains_number)

این نیز منجر به:

Is there any number present? True

بررسی کنید که آیا رشته حاوی عدد در پایتون با عبارات منظم است یا خیر

عبارات منظم هستند الگوهای جستجو طراحی شده تا با متن ورودی مطابقت داشته باشد. آنها انعطاف پذیر هستند و با توجه به ماهیت خود – می توانید تعداد دلخواه عبارات را برای همان الگو بنویسید تا جستجو کنید، و همچنین هر الگوی قابل انعطافی را که فکر می کنید پوشش دهید.

پایتون re ماژول برای نوشتن، کامپایل و مطابقت متن با عبارات منظم استفاده می شود. روش های مختلفی را به نمایش می گذارد، مانند match() که مطابق با اینکه یک رشته با یک الگو شروع می شود، search() که اولین رخداد احتمالاً بسیاری از مسابقات را در یک رشته پیدا می کند و findall() که همه موارد را بررسی می کند.

توجه داشته باشید: هر سه روش الف را می پذیرند pattern و search آرگومان و جستجو برای pattern در search رشته

پیشنهاد می‌کنیم بخوانید:  پایتون: لیست فایل ها در یک فهرست

الگویی که الف را مشخص می کند رقم است "\d+":

import re
input_string = "My name is Satyam & I am 22 yrs old"
match = re.search(r"\d+", input_string)
if match:
    print("Is there any number present?", "Yes")
else:
    print("Is there any number present?", "No")

را search() روش a را برمی گرداند re.Match شی، حاوی مطابقت یافت شده و شاخص های شروع و پایان:

<re.Match object; span=(25, 27), match='22'>

شی را می توان بر اساس یک مقدار بولی ارزیابی کرد روی آیا آن یک re.Match شی یا None. این نتیجه در:

Is there any number present? Yes

بر خلاف search() روش، findall() متد تمام رخدادهای الگو را به جای اولین مورد برمی گرداند:

import re
input_string = "My name is Satyam & I am 22 yrs old"
match = re.findall(r"\d+", input_string)
if match:
    print("Is there any number present?", "Yes")
else:
    print("Is there any number present?", "No")

این نتیجه در:

Is there any number present? Yes

محک زدن

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

%timeit ord_check()
%timeit isnumeric_check()
%timeit is_digit_check()
%timeit lambda_check()
%timeit regex_check()

این نتیجه در:

2.18 µs ± 51.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
2.04 µs ± 639 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
1.88 µs ± 448 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
5.07 µs ± 915 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
1.47 µs ± 3.41 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

به طور کلی رویکردهای حلقه for تقریباً در همان زمان اجرا می شوند، با هزینه کمی از روش های خاص. لامبدا با any() عملاً کندترین است (بسیاری از عملیات اضافی، به دلیل تبدیل یک لیست به یک لیست و سپس کاهش آن)، در حالی که Regular Expressions سریع ترین زمان اجرا را با کمترین واریانس در اطراف آن داشت (آنها به طور مداوم سریع هستند).

با این حال، روی متون ورودی طولانی تر، پیچیدگی های زمانی روی هر یک از رویکردهای مختلف، به ویژه بسته به آن، مورد تأکید قرار می گیرد روی تعداد ارقام منطبق (اعم از اینکه ارقام مشترک هستند یا نه):

import random
import string

input_string_random = ''.join(random.choices(string.ascii_uppercase + string.digits, k=1000))
print(input_string_random) 

input_string_with_single_digit = ''.join(random.choices(string.ascii_uppercase, k=1000)) + '1'
print(input_string_with_single_digit) 

رشته اول یک دنباله تصادفی با تعداد ارقام و کاراکترهای مساوی ایجاد می کند، در حالی که رشته دوم یک رشته فقط کاراکتری است که در پایان یک رقم تک رقمی است (بدترین پیچیدگی زمانی):

%timeit ord_check(input_string_random)
504 ns ± 22.6 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%timeit ord_check(input_string_with_single_digit)
76.2 µs ± 1.36 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit isnumeric_check(input_string_random)
756 ns ± 170 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%timeit isnumeric_check(input_string_with_single_digit)
76.2 µs ± 8.43 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit is_digit_check(input_string_random)
549 ns ± 102 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%timeit is_digit_check(input_string_with_single_digit)
65 µs ± 20.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit lambda_check(input_string_random)
114 µs ± 8.77 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit lambda_check(input_string_with_single_digit)
119 µs ± 6.23 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit regex_check(input_string_random)
996 ns ± 19.8 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%timeit regex_check(input_string_with_single_digit)
22.2 µs ± 1.77 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

با تعداد بازدید کم – عبارات منظم بیشترین عملکرد را دارند. با بسیاری از بازدیدها، رویکرد تابع لامبدا بیشترین عملکرد را دارد، و این پیچیدگی زمانی خود را حفظ می کند صرف نظر از اینکه ورودی دارای تعداد زیادی ضربه است یا یک. نقطه ضعف اصلی (محاسبات اضافی وقتی نرخ ضربه کم است) به نقطه قوت اصلی آن تبدیل می شود زیرا افزونگی آن را برای ورودی قوی می کند.

نتیجه

در این آموزش، ما به چندین روش برای بررسی اینکه آیا یک رشته در پایتون دارای حداقل یک کاراکتر است نگاهی انداختیم. ما نگاهی به آن انداخته ایم ord()، isnumeric()، isdigit() و isdecimal() تابع، و همچنین روش انتزاع این منطق با استفاده از فراخوانی تابع لامبدا map() و any(). سپس، عبارات منظم را بررسی کردیم و رویکردها را با ورودی های متفاوت محک زدیم.

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-02 19:50:04

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید