Preverite, ali niz vsebuje številko v Pythonu

Predstavitev

Ne glede na to, ali gradite skript za preverjanje za uporabniški vnos, obrazec za prijavo, ki od uporabnikov zahteva, da v geslo vključijo znak – preverjanje, ali niz vsebuje znak, ni neobičajna operacija.

V tej vadnici si bomo ogledali številne načine, kako lahko preverite, ali niz vsebuje števko/število v Pythonu, vključno z merilom uspešnosti za najučinkovitejši pristop na koncu.

Preverite, ali niz vsebuje številko v Pythonu

Obstaja več načinov, kako preveriti, ali a značaja je številka (ord(), isnumeric(), isdigit()), ki ga lahko povežete z zanko for, da preverite vsaj en pozitiven zadetek. Namesto tega lahko uporabite regularne izraze kot splošne ujemalce vzorcev, ki so prilagodljivi, zmogljivi in ​​zasnovani za uporabo v velikih korpusih besedila. Končno – vedno lahko map() vsakemu znaku podan pogojni stavek in vrnitev True is any() od njih povzročijo True.

Pri izbiri med temi je treba upoštevati učinkovitost metod, podrobnost in slog kodiranja, pa tudi naloge navzgor ali navzdol, povezane z operacijo.

Preverite, ali niz vsebuje številko z ord()

O ord() funkcija vzame znak in ga vrne ASCII vrednost:

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

Vrednost ASCII za 0 je 48, vrednost ASCII pa 9 je 57. Katera koli številka med temi bo z razširitvijo, imajo vrednost ASCII med 48 in 57. Zdaj, da preverimo, ali ima niz kakšno številko, preletimo celoten vhodni niz in preverimo vrednost ASCII vsakega znaka, če je vrednost ASCII večja od 47 in manjša od 58, pomeni, da je številka, in vrnili se bomo 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.")

Rezultat tega je:

Yes, the string contains a number.

Preverite, ali niz vsebuje številko z isnumeric()

O isnumeric() funkcija se vrne True če vhodni niz vsebuje samo številke, sicer vrne 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())

Rezultat tega je:

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

Opomba: O isnumeric() funkcija ne bo delovala, kot bi lahko pričakovali negativna ali lebdeča števila. Če posredujemo niz samo z negativnimi ali plavajočimi števili, se bo vrnil False, ker je - in . znaki, povezani z negativnimi števili in lebdečimi številkami, dejansko niso števila.

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

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

Čeprav so znaki samo nizi dolžine 1 v Pythonu – lahko ponavljate znake in uporabite isnumeric() da preverite, ali so številka:

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

Preverite, ali niz vsebuje številko z isdigit()

O isdigit() funkcija preveri, ali so vsi znaki v nizu števke. Če da – se vrne True, in če ne, se vrne False. Še enkrat, ker so znaki samo nizi dolžine 1 v Pythonu – to metodo lahko uporabite v zanki za vsak znak:

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

Opomba: O isdigit() metoda se obnaša samo na enak način kot isnumeric()in če mu posredujete niz, ki vsebuje plavajočo številko ali negativno število, False se vrne, ker posebni znaki niso številke. Na značajski ravni pa, če je dolg kot en True vrednost zadostuje za določitev, ali niz vsebuje številko – velja.

Razlika med isnumeric() in isdigit()?

Torej, v čem je razlika isnumeric() in isdigit()? Ko smo že pri tem – kaj pa isdecimal()?

  • isnumeric() preveri, ali je kateri koli znak a predstavitev unicode o številčna vrednost (ki vključuje rimske numerične predstavitve, nadnapise, podnapise in ulomke)
  • isdigit() preveri, ali je kateri koli znak a številka unicode (ki ne vključuje predstavitev rimskih številk, vključuje pa nadnapise in ulomke)
  • isdecimal() preveri, ali je kateri koli znak a decimalna številka (ki bi se vrnil False za vse, kar ni 0..9 v osnovi 10)

isnumeric() je najširša metoda, medtem ko isdecimal() je najožji med tremi.

Preverite, ali niz vsebuje številko z map() in any()

O map() funkcija izvede podano funkcijo za vsak element iterable, posredovan v funkciji preslikave. Vsak element iterable se posreduje funkciji kot parameter:

map(function, iterable)

O function se izvede za vsako postavko iterable. To omogoča zelo prilagodljivo in močno logiko, omejeno le z obsežnostjo function kličeš na vhod! Metoda vrne a map primerek, ki ga je mogoče preprosto spremeniti v druge zbirke, kot je seznam ali niz.

Napišemo lahko funkcijo, ki vrne logično vrednost, ki predstavlja, ali je znak število, in map() klic bo tako povzročil seznam logičnih vrednosti.

O any() vrne True če je kateri koli element posredovane iterable True, sicer se vrne False.

Če povežemo to dvoje skupaj – lahko ustvarimo kratek skript na visoki ravni in odstranimo zanko 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)

Rezultat tega je:

Is there a number present? True

Če je vaša funkcija enovrstična – je ni treba ekstrahirati kot imenovano funkcijo. Lahko pišete anonimno lambda funkcija namesto tega zaradi kratkosti:

Oglejte si naš praktični, praktični vodnik za učenje Gita z najboljšimi praksami, standardi, sprejetimi v panogi, in priloženo goljufijo. Nehajte Googlati ukaze Git in pravzaprav naučiti it!

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)

Rezultat tega je tudi:

Is there any number present? True

Preverite, ali niz vsebuje število v Pythonu z regularnimi izrazi

Regularni izrazi so iskalni vzorci zasnovan tako, da se primerja z vnesenim besedilom. So prilagodljivi in ​​glede na njihovo naravo – za isti vzorec, ki ga želite poiskati, lahko napišete poljubno število izrazov, prav tako lahko pokrijete kateri koli sledljiv vzorec, ki se ga spomnite.

Pythonova re modul se uporablja za pisanje, prevajanje in ujemanje besedila z regularnimi izrazi. Izpostavlja različne metode, kot npr match() ki se ujema s tem, ali se niz začne z vzorcem, search() ki najde prvo pojavitev po možnosti veliko ujemanj v nizu, in findall() ki preverja vse pojavitve.

Opomba: Vse tri metode sprejemajo a pattern in search argument in zaženite iskanje za pattern v search niz.

Vzorec, ki identificira a mestna 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")

O search() metoda vrne a re.Match objekt, ki vsebuje najdeno ujemanje ter začetni in končni indeks:


Objekt je mogoče ovrednotiti na logično vrednost glede na to, ali je a re.Match predmet oz None. Rezultat tega je:

Is there any number present? Yes

Za razliko od search() Postopek, findall() metoda vrne vse pojavitve vzorca namesto le prvega:

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

Rezultat tega je:

Is there any number present? Yes

Benchmarking

Kaj pa uspešnost? Če izluščite logiko in obrežete nepotrebne dele ter omejite metode samo na vrnitev rezultata, jih lahko preprosto primerjate enega z drugim na istem vnosu:

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

Rezultat tega je:

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)

Na splošno se pristopi for-loop izvajajo približno istočasno, z malo dodatnih stroškov zaradi posebnih metod. Lambda z any() je de facto najpočasnejši (veliko odvečnih operacij zaradi pretvorbe seznama v seznam in njegovega nato zmanjševanja), medtem ko so imeli regularni izrazi najhitrejši čas izvajanja z najmanjšo varianco (so dosledno hitri).

Vendar pa je pri daljših vnosnih besedilih poudarjena časovna zapletenost vsakega od različnih pristopov, zlasti glede na število ujemajočih se števk (ne glede na to, ali so števke pogoste ali ne):

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) 

Prvi niz ustvari naključno zaporedje s približno enakim številom števk in znakov, medtem ko je slednji samo znakovni niz z eno števko na koncu (najslabša časovna kompleksnost):

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

Z majhnim številom zadetkov – regularni izrazi so najučinkovitejši. S številnimi zadetki je pristop lambda funkcije najučinkovitejši in to ohranja svojo časovno kompleksnost ne glede na to ali ima vnos veliko zadetkov ali enega. Glavna slaba stran (odvečno računanje, ko je stopnja zadetkov nizka) se spremeni v njegovo glavno prednost, saj je zaradi redundance robusten za vnos.

zaključek

V tej vadnici smo si ogledali več načinov za preverjanje, ali niz v Pythonu vsebuje vsaj en znak. Ogledali smo si ord(), isnumeric(), isdigit() in isdecimal() funkcijo, kot tudi, kako abstrahirati to logiko s klicem funkcije lambda z uporabo map() in any(). Nato smo raziskali regularne izraze in primerjali pristope z različnimi vhodnimi podatki.

Časovni žig:

Več od Stackabuse