Ellenőrizze, hogy a karakterlánc tartalmaz-e számot a Pythonban

Bevezetés

Függetlenül attól, hogy ellenőrző szkriptet épít a felhasználói bevitelhez, egy bejelentkezési űrlapot, amely arra kéri a felhasználókat, hogy szerepeltessenek egy karaktert a jelszóban – annak ellenőrzése, hogy egy karakterlánc tartalmaz-e karaktert, nem ritka művelet.

Ebben az oktatóanyagban megvizsgáljuk, hogy milyen sokféle módon ellenőrizheti, hogy egy karakterlánc tartalmaz-e számjegyet/számot a Pythonban, beleértve a leghatékonyabb megközelítés referenciaértékét is.

Ellenőrizze, hogy a karakterlánc tartalmaz-e számot a Pythonban

Számos módja van annak ellenőrzésére, hogy a karakter egy szám (ord(), isnumeric(), isdigit()), amelyet for-hurokkal párosíthat, hogy legalább egyetlen pozitív találatot ellenőrizzen. Alternatív megoldásként használhatja a reguláris kifejezéseket általános mintaegyeztetőként, amelyek rugalmasak, hatékonyak és nagy szövegrészekre való alkalmazásra tervezték. Végül – mindig lehet map() minden karakter adott egy feltételes utasítást, és visszatér True is any() közülük eredményez True.

Ezek közötti választásnál figyelembe kell venni a módszerek hatékonyságát, a bőbeszédűséget és a kódolási stílust, valamint a művelethez kapcsolódó upstream vagy downstream feladatokat.

Ellenőrizze, hogy a karakterlánc tartalmaz-e számot az ord()

A ord() függvény vesz egy karaktert és visszaadja ASCII érték:

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

Az ASCII értéke 0 48, az ASCII értéke pedig 9 57. Bármely szám ezek között, kiterjesztve, ASCII értéke 48 és 57 között van. Most annak ellenőrzésére, hogy a karakterláncnak van-e bármilyen száma, bejárjuk a teljes bemeneti karakterláncot, és ellenőrizzük az egyes karakterek ASCII értékét, ha az ASCII érték nagyobb, mint 47 és kisebb, mint 58, akkor ez egy számot jelent, és visszatérünk. 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.")

Ennek eredményeként:

Yes, the string contains a number.

Ellenőrizze, hogy a karakterlánc tartalmaz-e számot az isnumeric()

A isnumeric() függvény visszatér True ha a bemeneti karakterlánc csak számokat tartalmaz, ellenkező esetben visszaadja 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())

Ennek eredményeként:

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

Jegyzet: A isnumeric() funkció nem fog úgy viselkedni, ahogyan azt elvárná negatív vagy lebegő számok. Ha csak negatív vagy lebegő számokat adunk át, akkor az vissza fog térni False, mert a - és a . a negatív számokhoz és lebegőpontokhoz társított karakterek valóban nem számok.

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

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

Mivel azonban a karakterek csak 1 hosszúságú karakterláncok a Pythonban, ismételheti a karaktereket, és isnumeric() annak ellenőrzéséhez, hogy számról van-e szó:

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.")

Ellenőrizze, hogy a karakterlánc tartalmaz-e számot az isdigit()

A isdigit() A függvény ellenőrzi, hogy egy karakterláncban szereplő összes karakter számjegy-e. Ha igen – visszajön True, és ha nem, akkor visszatér False. Ismétlem, mivel a karakterek csak 1 hosszúságú karakterláncok a Pythonban – ez a módszer minden karakterhez ciklusban használható:

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.")

Jegyzet: A isdigit() módszer csak ugyanúgy viselkedik, mint isnumeric(), és ha egy lebegőpontos vagy negatív számot tartalmazó karakterláncot ad át neki, False visszaküldésre kerül, mivel a speciális karakterek nem számok. Karakterszinten azonban, ha csak egy True érték elegendő annak meghatározásához, hogy a karakterlánc tartalmaz-e számot – ez alkalmazható.

Mi a különbség az isnumeric() és az isdigit() között?

Szóval, mi a különbség isnumeric() és a isdigit()? Ha már itt tartunk – mi a helyzet isdecimal()?

  • isnumeric() ellenőrzi, hogy valamelyik karakter a unicode ábrázolás Egy számérték (amely római numerikus ábrázolásokat, felső indexeket, alsó indexeket és törteket tartalmaz)
  • isdigit() ellenőrzi, hogy valamelyik karakter a unicode számjegy (amely nem tartalmazza a római numerikus ábrázolásokat, de tartalmazza a felső/alindexeket és a törteket)
  • isdecimal() ellenőrzi, hogy valamelyik karakter a decimális számjegy (ami visszatérne False bármire, ami nem 0..9 10-es alapban)

isnumeric() a legtágabb módszer, míg isdecimal() a legszűkebb a három között.

Ellenőrizze, hogy a karakterlánc tartalmaz-e számot a map() és any() segítségével

A map() függvény végrehajtja a megadott függvényt a leképezési függvényben átadott iterálható minden egyes eleméhez. Az iterálható elem minden eleme paraméterként átadásra kerül a függvénynek:

map(function, iterable)

A function minden elemére végrehajtódik iterable. Ez nagyon rugalmas és erőteljes logikát tesz lehetővé, amelyet csak a terjedelme korlátoz function hívod a bemenetet! A metódus visszaadja a map példány, amely könnyen átalakítható más gyűjteményekké, például listává vagy halmazzá.

Írhatunk egy függvényt, amely egy logikai értéket ad vissza, amely azt jelzi, hogy egy karakter szám-e, és a map() A hívás így a logikai értékek listáját eredményezi.

A any() Visszatér True ha az átadott iterálható bármely eleme az True, ellenkező esetben visszatér False.

A kettőt összefűzve magas szintű, rövid szkriptet hozhatunk létre, és elvonatkoztathatjuk a for-hurkot:

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)

Ennek eredményeként:

Is there a number present? True

Ha az Ön függvénye egysoros, akkor nem szükséges elnevezett függvényként kibontani. Írhatsz névtelenül lambda funkció inkább a rövidség kedvéért:

Tekintse meg gyakorlatias, gyakorlati útmutatónkat a Git tanulásához, amely tartalmazza a bevált gyakorlatokat, az iparág által elfogadott szabványokat és a mellékelt csalólapot. Hagyd abba a guglizást a Git parancsokkal, és valójában tanulni meg!

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)

Ez a következőket is eredményezi:

Is there any number present? True

Ellenőrizze, hogy a karakterlánc tartalmaz-e számot a Pythonban reguláris kifejezésekkel

A reguláris kifejezések keresési minták úgy tervezték, hogy illeszkedjenek a bemeneti szöveghez. Rugalmasak és természetükből adódóan – tetszőleges számú kifejezést írhat ugyanarra a mintára, hogy keressen, valamint lefedhet bármilyen vonható mintát.

Pythoné re A modul szöveg írására, fordítására és reguláris kifejezésekkel való párosítására szolgál. Különféle módszereket tár fel, mint pl match() ami megegyezik azzal, hogy egy karakterlánc mintával kezdődik, search() amely megkeresi egy karakterláncban esetleg sok egyezés első előfordulását, és findall() amely minden előfordulást ellenőriz.

Jegyzet: Mindhárom módszer elfogadja a pattern és a search érv, és futtasson egy keresést a pattern a search húr.

A minta, amely azonosítja a számjegy 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")

A search() metódus a re.Match objektum, amely tartalmazza a talált egyezést, valamint a kezdő és záró indexeket:


Az objektum logikai értékre értékelhető az alapján, hogy a re.Match tárgy vagy None. Ennek eredménye:

Is there any number present? Yes

Ellentétben a search() módszer, a findall() metódus a minta összes előfordulását adja vissza, nem csak az elsőt:

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")

Ennek eredményeként:

Is there any number present? Yes

benchmarking

Mi a helyzet az előadással? Ha kivonja a logikát és levágja a szükségtelen részeket, és a metódusokat csak az eredmény visszaadására korlátozza, akkor ugyanazon a bemeneten könnyedén összehasonlíthatja őket egymással:

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

Ennek eredményeként:

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)

Általában a for-loop megközelítések nagyjából ugyanabban az időben futnak be, kevés többletköltséggel az egyes módszerekből. Lambda vele any() defacto a leglassabb (sok redundáns művelet, a lista listává alakítása, majd csökkentése miatt), míg a reguláris kifejezések futásideje a leggyorsabb a legkisebb szórással (konzisztensen gyorsak).

Hosszabb beviteli szövegeknél azonban az egyes megközelítések időbeli bonyolultsága hangsúlyossá válik, különösen az egyező számjegyek számától függően (függetlenül attól, hogy a számjegyek közösek-e vagy sem):

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) 

Az első karakterlánc véletlenszerű sorozatot generál körülbelül azonos számú számjegyből és karakterből, míg az utóbbi egy csak karakterből álló karakterlánc, amelynek a végén egy számjegy (legrosszabb időbonyolítás):

%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)

Alacsony találati számmal – A reguláris kifejezések a legeredményesebbek. Sok találat mellett a lambda funkciós megközelítés a legteljesítményesebb, és ez megőrzi időbeli összetettségét függetlenül attól, hogy a bemenetnek sok vagy egy találata van. A fő hátrány (redundáns számítás alacsony találati arány esetén) a fő erősségévé válik, mivel a redundancia robusztussá teszi a bevitelt.

Következtetés

Ebben az oktatóanyagban több módszert is megvizsgáltunk annak ellenőrzésére, hogy a Pythonban található karakterlánc tartalmaz-e legalább egy karaktert. Megnéztük a ord(), isnumeric(), isdigit() és a isdecimal() függvényt, valamint hogyan lehet ezt a logikát elvonatkoztatni egy lambda függvényhívás segítségével map() és a any(). Ezután megvizsgáltuk a reguláris kifejezéseket, és összehasonlítottuk a megközelítéseket különböző bemenetekkel.

Időbélyeg:

Még több Stackabus