esittely
Olitpa rakentamassa varmistusskriptiä käyttäjän syöttämistä varten, kirjautumislomake, joka pyytää käyttäjiä lisäämään merkin salasanaan – sen tarkistaminen, sisältääkö merkkijono merkin, ei ole harvinainen toimenpide.
Tässä opetusohjelmassa – tarkastelemme monia tapoja, joilla voit tarkistaa, sisältääkö merkkijono numeron/numeron Pythonissa, mukaan lukien vertailukohta tehokkaimmalle lähestymistavalle.
Tarkista Pythonissa, sisältääkö merkkijono numeron
On useita tapoja tarkistaa, onko a merkki on numero (ord()
, isnumeric()
, isdigit()
), jonka voit yhdistää for-silmukalla tarkistaaksesi ainakin yhden positiivisen osuman. Vaihtoehtoisesti voit käyttää säännöllisiä lausekkeita yleisinä kuviovastaavina, jotka ovat joustavia, tehokkaita ja suunniteltu käytettäväksi suurissa tekstikappaleissa. Lopuksi – voit aina map()
jokaiselle merkille annetaan ehdollinen lause, ja paluu True
is any()
niistä johtaa True
.
Näiden välillä valittaessa tulee ottaa huomioon menetelmien tehokkuus, sananmukaisuus ja koodaustyyli sekä toimintaan liittyvät ylä- tai loppupään tehtävät.
Tarkista, sisältääkö merkkijono numeron komennolla ord()
- ord()
funktio ottaa merkin ja palauttaa sen ASCII arvo:
print(ord('0'))
print(ord('9'))
ASCII-arvo 0
on 48 ja ASCII-arvo 9
on 57. Mikä tahansa luku näiden välissä, laajentaa ASCII-arvo on välillä 48-57. Nyt tarkistaaksemme onko merkkijonossa jokin numero, käymme läpi koko syötemerkkijonon ja tarkistamme jokaisen merkin ASCII-arvon. Jos ASCII-arvo on suurempi kuin 47 ja pienempi kuin 58, se tarkoittaa, että se on numero, ja palaamme 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.")
Tämä johtaa:
Yes, the string contains a number.
Tarkista, sisältääkö merkkijono numeron isnumeric()
- isnumeric()
toiminto palaa True
jos syötemerkkijono sisältää vain numeroita, muussa tapauksessa se palauttaa 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())
Tämä johtaa:
String is whole numeric? True
String is whole numeric? False
Huomautus: - isnumeric()
toiminto ei toimi odotetulla tavalla negatiivisia tai kelluvia lukuja. Jos välitämme merkkijonon, jossa on vain negatiivisia numeroita tai kelluvia lukuja, se palaa False
, koska -
ja .
negatiivisiin lukuihin ja liukuihin liittyvät merkit ovat todellakin, eivät numeroita.
str1 = "-918"
print("String is whole numeric?", str1.isnumeric())
str2 = "91.8"
print("String is whole numeric?", str2.isnumeric())
Koska merkit ovat kuitenkin vain merkkijonoja, joiden pituus on 1 Pythonissa, voit iteroida merkkejä ja käyttää isnumeric()
tarkistaaksesi, ovatko ne numeroita:
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.")
Tarkista, sisältääkö merkkijono Numeron ja isdigit()
- isdigit()
toiminto tarkistaa, ovatko kaikki merkkijonon merkit numeroita. Jos kyllä - se palaa True
, ja jos ei, se palaa False
. Jälleen, koska merkit ovat vain merkkijonoja, joiden pituus on 1 Pythonissa, tätä menetelmää voidaan käyttää silmukassa jokaiselle merkille:
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.")
Huomautus: - isdigit()
menetelmä toimii vain samalla tavalla kuin isnumeric()
, ja jos annat sille merkkijonon, joka sisältää kelluvan tai negatiivisen luvun, False
palautetaan, koska erikoismerkit eivät ole numeroita. Hahmotasolla kuitenkin, jos yhtä kauan True
arvo riittää määrittämään, sisältääkö merkkijono numeron – se on sovellettavissa.
Ero isnumeric()- ja isdigit()-funktioiden välillä?
Joten, mikä on ero isnumeric()
ja isdigit()
? Kun ollaan siinä – entä isdecimal()
?
isnumeric()
tarkistaa, onko jokin merkki a unicode-esitys a numeerinen arvo (joka sisältää roomalaiset numerot, yläindeksit, alaindeksit ja murtoluvut)isdigit()
tarkistaa, onko jokin merkki a unicode-numero (joka ei sisällä roomalaisia numeroita, mutta sisältää ylä-/alaindeksit ja murtoluvut)isdecimal()
tarkistaa, onko jokin merkki a desimaalinumero (joka palaisiFalse
kaikkeen, mikä ei ole0..9
pohjassa 10)
isnumeric()
on laajin menetelmä, kun taas isdecimal()
on kapein näiden kolmen välillä.
Tarkista, sisältääkö merkkijono numeron käyttämällä map() ja any()
- map()
toiminto suorittaa tarjotun toiminnon jokaiselle karttafunktiossa välitetyn iteroitavan elementille. Jokainen iteroitavan elementti välitetään funktiolle parametrina:
map(function, iterable)
- function
suoritetaan jokaiselle kohteelle iterable
. Tämä mahdollistaa erittäin joustavan ja tehokkaan logiikan, jota rajoittaa vain laajuus function
soitat syötteeseen! Metodi palauttaa a map
esimerkki, joka voidaan helposti muuttaa muiksi kokoelmiksi, kuten luetteloksi tai joukoksi.
Voimme kirjoittaa funktion, joka palauttaa loogisen arvon, joka ilmaisee, onko merkki numero, ja
map()
kutsu johtaa siten loogisten arvojen luetteloon.
- any()
Tuotto True
jos jokin ohitetun iteroitavan elementti on True
, muuten se palaa False
.
Yhdistämällä nämä kaksi yhteen – voimme luoda korkean tason, lyhyen käsikirjoituksen ja abstraktin for-silmukan:
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)
Tämä johtaa:
Is there a number present? True
Jos funktiosi on yksilinjainen, sitä ei tarvitse purkaa nimettynä funktiona. Voit kirjoittaa anonyymin lambda -toiminto sen sijaan lyhyyden vuoksi:
Tutustu käytännönläheiseen, käytännölliseen Gitin oppimisoppaaseemme, jossa on parhaat käytännöt, alan hyväksymät standardit ja mukana tuleva huijauslehti. Lopeta Git-komentojen googlailu ja oikeastaan oppia se!
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)
Tästä seuraa myös:
Is there any number present? True
Tarkista, sisältääkö merkkijono numeron Pythonissa säännöllisillä lausekkeilla
Säännölliset lausekkeet ovat hakumalleja suunniteltu vastaamaan syöttötekstiä. Ne ovat joustavia ja luonteensa vuoksi – voit kirjoittaa mielivaltaisen määrän ilmaisuja samalle kuviolle etsittäväksi sekä peittää minkä tahansa kuvittelemasi kuvion.
Pythonin re
moduulia käytetään tekstin kirjoittamiseen, kokoamiseen ja yhdistämiseen säännöllisiin lausekkeisiin. Se paljastaa erilaisia menetelmiä, kuten match()
mikä vastaa sitä, alkaako merkkijono kuviolla, search()
joka löytää ensimmäisen mahdollisesti useiden osumien esiintymisen merkkijonosta, ja findall()
joka tarkistaa kaikki tapahtumat.
Huomautus: Kaikki kolme menetelmää hyväksyvät a pattern
ja search
argumentti ja suorita haku pattern
vuonna search
merkkijono.
Kuvio, joka tunnistaa a numero 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()
method palauttaa a re.Match
objekti, joka sisältää löydetyn osuman sekä aloitus- ja loppuindeksit:
Objekti voidaan arvioida loogiseksi arvoksi sen perusteella, onko se a re.Match
esine tai None
. Tästä seuraa:
Is there any number present? Yes
Toisin kuin search()
menetelmällä, findall()
menetelmä palauttaa kaikki kuvion esiintymät ensimmäisen sijasta:
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")
Tämä johtaa:
Is there any number present? Yes
benchmarking
Entä suorituskyky? Jos purat logiikan ja leikkaat tarpeettomat osat rajoittamalla menetelmät vain tuloksen palauttamiseen, voit helposti verrata niitä toisiinsa samalla syötteellä:
%timeit ord_check()
%timeit isnumeric_check()
%timeit is_digit_check()
%timeit lambda_check()
%timeit regex_check()
Tämä johtaa:
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)
Yleensä for-loop-lähestymistavat toimivat suunnilleen samaan aikaan, ja tietyt menetelmät aiheuttavat vain vähän lisäkustannuksia. Lambda kanssa any()
on defacto hitain (paljon redundantteja operaatioita, koska luettelo muunnetaan luetteloksi ja sen jälkeen pienennetään), kun taas Säännöllisillä lausekkeilla oli nopein suoritusaika pienimmällä varianssilla (ne ovat jatkuvasti nopeita).
Pidemmissä syöttöteksteissä kuitenkin korostuvat kunkin eri lähestymistavan aikamonimutkaisuus, erityisesti riippuen täsmäävien numeroiden määrästä (ovatko numerot yhteisiä vai eivät):
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)
Ensimmäinen merkkijono luo satunnaisen sekvenssin, jossa on suunnilleen yhtä suuri määrä numeroita ja merkkejä, kun taas jälkimmäinen on vain merkkijono, jonka lopussa on yksi numero (pahin aika monimutkaisuus):
%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)
Pienellä osumien määrällä – Säännölliset lausekkeet ovat tehokkaimpia. Monilla osumilla lambda-toiminto on tehokkain, ja se säilyttää ajan monimutkaisuuden riippumatta siitä, onko syötteellä monta osumaa vai yksi. Suurin haittapuoli (reduntiivinen laskenta, kun osumaprosentti on alhainen) muutetaan sen päävahvuudeksi, koska redundanssi tekee siitä vakaan syöttämisen.
Yhteenveto
Tässä opetusohjelmassa tarkastelimme useita tapoja tarkistaa, sisältääkö Pythonin merkkijono vähintään yhden merkin. Olemme käyneet katsomassa ord()
, isnumeric()
, isdigit()
ja isdecimal()
funktio, sekä kuinka abstrakti tämä logiikka lambda-funktiokutsulla käyttämällä map()
ja any()
. Sitten tutkimme säännöllisiä lausekkeita ja vertailimme lähestymistapoja vaihtelevalla syötteellä.