บทนำ
ไม่ว่าคุณจะสร้างสคริปต์การยืนยันสำหรับการป้อนข้อมูลของผู้ใช้ แบบฟอร์มเข้าสู่ระบบที่ขอให้ผู้ใช้ใส่อักขระในรหัสผ่าน การตรวจสอบว่าสตริงมีอักขระหรือไม่ถือเป็นการดำเนินการที่ผิดปกติ
ในบทช่วยสอนนี้ เราจะดูหลายวิธีที่คุณสามารถตรวจสอบว่าสตริงมีตัวเลข/ตัวเลขใน Python หรือไม่ รวมถึงการวัดประสิทธิภาพสำหรับแนวทางที่มีประสิทธิภาพสูงสุดในตอนท้าย
ตรวจสอบว่าสตริงมีตัวเลขใน Python หรือไม่
มีหลายวิธีในการตรวจสอบว่ามี ตัวอักษร เป็นตัวเลข (ord()
, isnumeric()
, isdigit()
) ซึ่งคุณสามารถจับคู่กับ for-loop เพื่อตรวจสอบการตีเชิงบวกอย่างน้อยหนึ่งครั้ง หรือคุณสามารถใช้นิพจน์ทั่วไปเป็นตัวจับคู่รูปแบบทั่วไป ซึ่งมีความยืดหยุ่น มีประสิทธิภาพ และออกแบบมาเพื่อใช้กับคลังข้อความขนาดใหญ่ ในที่สุดคุณก็ทำได้เสมอ map()
อักขระแต่ละตัวได้รับคำสั่งแบบมีเงื่อนไขและส่งคืน True
is any()
ของพวกเขาส่งผลให้ True
.
การเลือกระหว่างสิ่งเหล่านี้ควรคำนึงถึงประสิทธิภาพของวิธีการ การใช้คำฟุ่มเฟือย และรูปแบบการเขียนโค้ด ตลอดจนงานต้นน้ำหรือปลายน้ำที่เกี่ยวข้องกับการดำเนินการ
ตรวจสอบว่าสตริงมีตัวเลขด้วย ord()
พื้นที่ ord()
ฟังก์ชั่นรับอักขระและส่งกลับ ASCII ราคา:
print(ord('0'))
print(ord('9'))
ค่า ASCII ของ 0
คือ 48 และค่า ASCII ของ 9
คือ 57 จำนวนใดๆ ระหว่างนี้ จะขยายออกไป มีค่า ASCII อยู่ระหว่าง 48 ถึง 57. ตอนนี้เพื่อตรวจสอบว่าสตริงมีตัวเลขใดๆ หรือไม่ เราจะตรวจสอบสตริงอินพุตทั้งหมดและตรวจสอบค่า ASCII ของอักขระแต่ละตัว หากค่า ASCII มากกว่า 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 ใน Python คุณจึงสามารถวนซ้ำอักขระและใช้งานได้ 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 ใน Python ดังนั้นวิธีนี้จึงสามารถใช้ในการวนซ้ำสำหรับอักขระแต่ละตัวได้:
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 ตัวเลขยูนิโค้ด (ซึ่งไม่รวมการแสดงตัวเลขโรมัน แต่รวมซุปเปอร์/ตัวห้อยและเศษส่วน)isdecimal()
ตรวจสอบว่ามีอักขระใดเป็น a หรือไม่ เลขฐานสิบ (ซึ่งจะกลับมา.False
เพื่ออะไรก็ตามที่ไม่ใช่0..9
ในฐาน 10)
isnumeric()
เป็นวิธีการที่กว้างที่สุดในขณะนั้น isdecimal()
แคบที่สุดระหว่างทั้งสาม
ตรวจสอบว่าสตริงมีตัวเลขพร้อม map() และ any()
พื้นที่ map()
ฟังก์ชั่น ดำเนินการฟังก์ชั่นที่ให้มาสำหรับแต่ละองค์ประกอบของการวนซ้ำที่ส่งผ่านในฟังก์ชั่นแผนที่ แต่ละองค์ประกอบของ iterable จะถูกส่งผ่านไปยังฟังก์ชันเป็นพารามิเตอร์:
map(function, iterable)
พื้นที่ function
ถูกดำเนินการสำหรับทุกรายการของ iterable
. สิ่งนี้ช่วยให้เกิดตรรกะที่ยืดหยุ่นและทรงพลังมาก โดยมีขอบเขตเพียงขอบเขตของความกว้างขวางเท่านั้น function
คุณโทรเข้า! วิธีการส่งกลับค่า map
ซึ่งสามารถเปลี่ยนเป็นคอลเลกชันอื่นๆ เช่น รายการหรือชุดได้อย่างง่ายดาย
เราสามารถเขียนฟังก์ชันที่คืนค่าบูลีนเพื่อแสดงว่าอักขระนั้นเป็นตัวเลขหรือไม่ และ
map()
การเรียกจะส่งผลให้เกิดรายการค่าบูลีน
พื้นที่ any()
รับคืน True
หากองค์ประกอบใด ๆ ของการทำซ้ำที่ผ่านไปได้คือ True
มิฉะนั้นก็จะส่งคืน False
.
การรวมสองสิ่งนี้เข้าด้วยกัน - เราสามารถสร้างสคริปต์สั้นระดับสูงและสรุป for-loop ออกไปได้:
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
หากฟังก์ชันของคุณเป็นแบบซับเดียว คุณไม่จำเป็นต้องแยกฟังก์ชันดังกล่าวเป็นฟังก์ชันที่มีชื่อ คุณสามารถเขียนแบบไม่ระบุชื่อได้ ฟังก์ชันแลมบ์ดา แทนเพื่อความกระชับ:
ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!
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
ตรวจสอบว่าสตริงมีตัวเลขใน Python ด้วยนิพจน์ทั่วไปหรือไม่
นิพจน์ทั่วไปคือ รูปแบบการค้นหา ออกแบบมาให้จับคู่กับข้อความที่ป้อน พวกมันมีความยืดหยุ่นและเป็นไปตามธรรมชาติ คุณสามารถเขียนสำนวนจำนวนเท่าใดก็ได้สำหรับรูปแบบเดียวกันเพื่อค้นหา และยังครอบคลุมรูปแบบที่เข้าใจได้ง่ายที่คุณนึกออกด้วย
Python ของ re
โมดูลนี้ใช้ในการเขียน คอมไพล์ และจับคู่ข้อความกับนิพจน์ทั่วไป โดยจะเผยวิธีการต่างๆ เช่น match()
ซึ่งจับคู่ว่าสตริงขึ้นต้นด้วยรูปแบบหรือไม่ search()
ซึ่งค้นหาการเกิดขึ้นครั้งแรกของรายการที่ตรงกันหลายรายการในสตริง และ findall()
ซึ่งจะตรวจสอบเหตุการณ์ทั้งหมด
หมายเหตุ ทั้งสามวิธียอมรับ a pattern
และ search
อาร์กิวเมนต์และดำเนินการค้นหา pattern
ใน search
เชือก
รูปแบบที่ระบุก เลข is "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
วัตถุหรือ 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-loop จะทำงานในเวลาเดียวกันโดยมีค่าใช้จ่ายเพียงเล็กน้อยจากวิธีการเฉพาะ แลมบ์ดาด้วย any()
defacto ช้าที่สุด (การดำเนินการซ้ำซ้อนจำนวนมาก เนื่องจากการแปลงรายการเป็นรายการแล้วลดขนาดลง) ในขณะที่นิพจน์ทั่วไปมีรันไทม์ที่เร็วที่สุดโดยมีความแปรปรวนน้อยที่สุด (รวดเร็วสม่ำเสมอ)
อย่างไรก็ตาม ในการป้อนข้อความที่ยาวขึ้น ความซับซ้อนของเวลาในแต่ละวิธีที่แตกต่างกันจะถูกเน้น โดยเฉพาะอย่างยิ่งขึ้นอยู่กับจำนวนหลักที่ตรงกัน (ไม่ว่าตัวเลขจะเป็นตัวเลขร่วมหรือไม่ก็ตาม):
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)
ด้วยจำนวนการเข้าชมที่น้อย – นิพจน์ทั่วไปจึงมีประสิทธิภาพมากที่สุด ด้วยการเข้าชมจำนวนมาก วิธีฟังก์ชัน lambda จึงมีประสิทธิภาพมากที่สุด และมันก็เป็นเช่นนั้น ยังคงความซับซ้อนของเวลาไว้ ไม่ว่าอินพุตจะมี Hit จำนวนมากหรือหนึ่งรายการก็ตาม ข้อเสียเปรียบหลัก (การคำนวณซ้ำซ้อนเมื่ออัตราการเข้าชมต่ำ) กลายเป็นจุดแข็งหลัก เนื่องจากความซ้ำซ้อนทำให้อินพุตมีความแข็งแกร่ง
สรุป
ในบทช่วยสอนนี้ เราได้ดูหลายวิธีในการตรวจสอบว่าสตริงใน Python มีอักขระอย่างน้อยหนึ่งตัวหรือไม่ เราได้ดูที่ ord()
, isnumeric()
, isdigit()
และ isdecimal()
ตลอดจนวิธีสรุปตรรกะนี้ด้วยการเรียกใช้ฟังก์ชัน lambda map()
และ any()
. จากนั้น เราได้สำรวจนิพจน์ทั่วไปและเปรียบเทียบแนวทางด้วยอินพุตที่แตกต่างกัน