Kontrollige, kas string sisaldab Pythonis numbrit

Sissejuhatus

Olenemata sellest, kas loote kasutaja sisestamiseks kinnitusskripti, sisselogimisvormi, mis palub kasutajatel lisada parooli märgi – kontrollimine, kas string sisaldab märki, pole haruldane toiming.

Selles õpetuses vaatleme paljusid viise, kuidas saate Pythonis kontrollida, kas string sisaldab numbrit/numbrit, sealhulgas kõige tõhusama lähenemisviisi etalon.

Kontrollige, kas string sisaldab Pythonis numbrit

On mitmeid viise, kuidas kontrollida, kas a iseloom on number (ord(), isnumeric(), isdigit()), mille saate siduda for-tsükliga, et kontrollida vähemalt üht positiivset tabamust. Teise võimalusena saate üldiste mustrite sobitajatena kasutada regulaaravaldisi, mis on paindlikud, võimsad ja mõeldud kasutamiseks suurtes tekstikorpustes. Lõpuks - saate alati map() igale märgile antakse tingimuslause ja tagastatakse True is any() neist tuleneb True.

Nende vahel valides tuleks arvesse võtta meetodite tõhusust, paljusõnalisust ja kodeerimisstiili, samuti operatsiooniga seotud üles- või allavoolu ülesandeid.

Kontrollige, kas string sisaldab numbrit käsuga ord()

. ord() funktsioon võtab märgi ja tagastab selle ASCII väärtus:

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

ASCII väärtus 0 on 48 ja ASCII väärtus 9 on 57. Suvaline arv nende vahel ASCII väärtus on vahemikus 48 kuni 57. Nüüd, et kontrollida, kas stringil on arv, läbime kogu sisendstringi ja kontrollime iga märgi ASCII väärtust. Kui ASCII väärtus on suurem kui 47 ja väiksem kui 58, tähendab see, et see on arv ja me tagastame 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.")

Selle tulemuseks on:

Yes, the string contains a number.

Kontrollige, kas string sisaldab numbrit koos isnumeric()

. isnumeric() funktsioon tagastab True kui sisendstring sisaldab ainult numbreid, tagastab see muul juhul 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())

Selle tulemuseks on:

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

Märge: . isnumeric() funktsioon ei käitu nii, nagu võite oodata negatiivsed või ujuvarvud. Kui me edastame stringi, millel on ainult negatiivsed või ujuvarvud, tagastatakse see False, sest - ja . negatiivsete arvude ja ujukitega seotud märgid on tõepoolest, mitte numbrid.

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

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

Kuna aga märgid on Pythonis vaid 1 pikkused stringid, saate tähemärke korrata ja kasutada isnumeric() et kontrollida, kas need on numbrid:

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

Kontrollige, kas string sisaldab numbrit koos isdigit()

. isdigit() funktsioon kontrollib, kas kõik stringi märgid on numbrid. Kui jah - see naaseb Trueja kui ei, siis naaseb False. Jällegi, kuna märgid on Pythonis vaid 1 pikkused stringid, saab seda meetodit kasutada tsüklina iga märgi jaoks:

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

Märge: . isdigit() meetod käitub ainult samamoodi nagu isnumeric(), ja kui annate sellele stringi, mis sisaldab ujukarvu või negatiivset arvu, False tagastatakse, kuna erimärgid ei ole numbrid. Tegelaste tasemel, kuigi nii kaua kui üks True väärtusest piisab, et teha kindlaks, kas string sisaldab numbrit – see on rakendatav.

Erinevus isnumeric() ja isdigit() vahel?

Niisiis, mis vahe on isnumeric() ja isdigit()? Kui me asja juures oleme – mis sellest isdecimal()?

  • isnumeric() kontrollib, kas mõni märk on a unicode esitus kohta numbriline väärtus (mis sisaldab rooma numbrite esitusi, ülaindekseid, alaindekseid ja murde)
  • isdigit() kontrollib, kas mõni märk on a unicode number (mis ei sisalda rooma numbreid, kuid sisaldab ülemisi/alaindekseid ja murde)
  • isdecimal() kontrollib, kas mõni märk on a kümnendkoht (mis tuleks tagasi False kõige jaoks, mida pole 0..9 baasis 10)

isnumeric() on kõige laiem meetod, samas isdecimal() on nende kolme vahel kõige kitsam.

Kontrollige, kas string sisaldab numbrit koos map() ja any()

. map() funktsioon täidab pakutud funktsiooni iga kaardifunktsioonis läbitud itereeritava elemendi jaoks. Iga itereeritava element edastatakse funktsioonile parameetrina:

map(function, iterable)

. function täidetakse iga üksuse jaoks iterable. See võimaldab väga paindlikku ja võimsat loogikat, mida piirab ainult selle ulatus function helistad sisendile! Meetod tagastab a map näiteks, mida saab hõlpsasti muuta muudeks kogudeks, näiteks loendiks või komplektiks.

Saame kirjutada funktsiooni, mis tagastab tõeväärtuse, mis näitab, kas märk on arv, ja map() kõne tulemuseks on tõeväärtuste loend.

. any() Tulu True kui mõni läbitud itereeritava element on True, vastasel juhul naaseb False.

Nende kahe ühendamine – saame luua kõrgetasemelise lühikese skripti ja abstraktse for-loopi:

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)

Selle tulemuseks on:

Is there a number present? True

Kui teie funktsioon on ühekihiline, pole vaja seda nimefunktsioonina ekstraktida. Võite kirjutada anonüümselt lambda funktsioon selle asemel lühiduse huvides:

Tutvuge meie praktilise ja praktilise Giti õppimise juhendiga, mis sisaldab parimaid tavasid, tööstusharus aktsepteeritud standardeid ja kaasas olevat petulehte. Lõpetage Giti käskude guugeldamine ja tegelikult õppima seda!

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)

Selle tulemuseks on ka:

Is there any number present? True

Kontrollige, kas string sisaldab regulaaravaldistega Pythonis numbrit

Regulaaravaldised on otsingumustrid loodud sobitama sisendtekstiga. Need on paindlikud ja nende olemust arvestades – saate sama mustri jaoks otsida suvalise arvu avaldisi ja katta mis tahes tõmmatavat mustrit.

Pythoni oma re moodulit kasutatakse teksti kirjutamiseks, koostamiseks ja vastavusse viimiseks regulaaravaldistega. See paljastab erinevaid meetodeid, nagu match() mis vastab sellele, kas string algab mustriga, search() mis leiab stringis võimalike paljude vastete esmakordse esinemise ja findall() mis kontrollib kõiki juhtumeid.

Märge: Kõik kolm meetodit aktsepteerivad a pattern ja search argument ja käivitage otsing pattern aasta search string.

Muster, mis identifitseerib a number 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() meetod tagastab a re.Match objekt, mis sisaldab leitud vastet ning algus- ja lõpuindekseid:


Objekti saab hinnata tõeväärtuseks selle põhjal, kas see on a re.Match objekt või None. Selle tulemuseks on:

Is there any number present? Yes

Erinevalt search() meetod, findall() meetod tagastab kõik mustri esinemised, mitte ainult esimese:

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

Selle tulemuseks on:

Is there any number present? Yes

Benchmarking

Aga esinemine? Kui eraldate loogika ja kärpite mittevajalikud osad, piirates meetodid ainult tulemuse tagastamisega, saate neid samas sisendis hõlpsasti üksteisega võrrelda:

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

Selle tulemuseks on:

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)

Üldjuhul käivad for-loop lähenemisviisid umbes samal ajal, konkreetsete meetoditega kaasnevad vähesed lisakulud. Lambda koos any() on defacto kõige aeglasem (palju üleliigseid toiminguid loendi loendiks teisendamise ja seejärel vähendamise tõttu), samas kui regulaaravaldistel oli kiireim käitusaeg ja selle ümber kõige väiksem dispersioon (need on pidevalt kiired).

Pikemate sisestustekstide puhul rõhutatakse aga iga erineva lähenemisviisi ajalist keerukust, eriti sõltuvalt sobitatud numbrite arvust (olenemata sellest, kas numbrid on tavalised või mitte):

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) 

Esimene string genereerib juhusliku jada, milles on ligikaudu võrdne arv numbreid ja märke, samas kui viimane on ainult märgist koosnev string, mille lõpus on üks number (halvim ajaline keerukus):

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

Madala tabamuste arvuga – regulaaravaldised on kõige tõhusamad. Paljude tabamuste korral on lambda-funktsiooni lähenemisviis kõige tõhusam ja see säilitab oma aja keerukuse olenemata sellest, kas sisendil on mitu tabamust või üks. Peamine negatiivne külg (liigne arvutus, kui tabamusmäär on madal) muudetakse selle peamiseks tugevuseks, kuna liiasus muudab selle sisestamise tugevaks.

Järeldus

Selles õpetuses vaatlesime mitmeid viise, kuidas kontrollida, kas Pythoni string sisaldab vähemalt ühte märki. Vaatasime üle ord(), isnumeric(), isdigit() ja isdecimal() funktsiooni, samuti seda, kuidas seda loogikat lambda-funktsiooni kõne abil abstraktselt võtta map() ja any(). Seejärel uurisime regulaaravaldisi ja võrdlesime lähenemisviise erineva sisendiga.

Ajatempel:

Veel alates Stackabus