Come sapere se la stringa inizia con un numero con Python?


95

Ho una stringa che inizia con un numero (da 0 a 9) So di poterlo "o" 10 casi di test usando startswith () ma probabilmente c'è una soluzione più ordinata

quindi invece di scrivere

if (string.startswith('0') || string.startswith('2') ||
    string.startswith('3') || string.startswith('4') ||
    string.startswith('5') || string.startswith('6') ||
    string.startswith('7') || string.startswith('8') ||
    string.startswith('9')):
    #do something

Esiste un modo più intelligente / più efficiente?


Se viene posta la domanda: "È troppo ripetitivo?", Le probabilità sono - in un linguaggio di alto livello - la risposta è "Perché, sì, è sicuro". Essere pigro!

42
Ti sei perso string.startswith('1').
MAK

2
@Illusionist Come è scritto, la tua domanda significa che vuoi rilevare le stringhe che iniziano con una sola cifra. In tal caso, la risposta giusto tra i seguenti, non sono quelli che utilizzano s[0]o s[:1]ma la soluzione di John Machin: if s.startswith(tuple('0123456789')). Inoltre, questa soluzione solleva un errore quando s è una sequenza come una tupla o una lista, i cui casi producono lo stesso risultato come se fosse una stringa. - Un'altra soluzione è una regex il cui pattern è '\ d (? = \ D)' ma l'uso di regex è superfluo qui.
eyquem

3
Essere solo pedante: stringè un modulo nella libreria standard e probabilmente non dovrebbe essere usato come nome di variabile. docs.python.org/2/library/string.html
gak

Risposte:


177

La stringlibreria di Python ha un isdigit()metodo:

string[0].isdigit()

5
Il string modulo di Python2 non ha metodi ed isdigitè un metodo di stre unicodeoggetti.
John Machin

3
@plaes: -1 a causa di quanto sopra INOLTRE si arresta in modo anomalo se s == ""
John Machin

4
Guarda la mia risposta che non si rompe per una stringa vuota:string[:1].isdigit()
PascalVKooten

25
>>> string = '1abc'
>>> string[0].isdigit()
True

Non sono un tipo Python, quindi forse puoi aiutarmi su questo: questa funzione bombarderà "", dove non c'è string[0]?
corsiKa

sì, sicuramente lo farà. potresti usare (string o 'x') [0] .isdigit () per correggerlo per '' o None
jcomeau_ictx

30
Potresti provare string[:1].isdigit(), che si chiuderà felicemente con una stringa vuota.
Simon Callan

2
perché non è la mia risposta; il mio è ancora migliore nel caso in cui il programmatore desideri che venga lanciata un'eccezione su una stringa vuota.
jcomeau_ictx

1
@jcomeau_ictx esattamente giusto. mai programmare in modo difensivo. se la stringa è inaspettatamente vuota, dovrebbe verificarsi un errore e non dovrebbe essere comunque gestito automaticamente. Alcune scuole di pensiero dicono che dovresti gestire con garbo e catturare le eccezioni che non sono critiche come avvertimento e mantenere il programma in corso. Non sono di questa mentalità per la maggior parte dei casi d'uso. La specificità nelle funzioni e nel codice che stai scrivendo aiuta a mitigare i casi limite in cui avresti bisogno di codice difensivo più spesso.
jamescampbell

10

a volte, puoi usare regex

>>> import re
>>> re.search('^\s*[0-9]',"0abc")
<_sre.SRE_Match object at 0xb7722fa8>

eccessivo! Perché usare re quando puoi farlo nei bultins
Jakob Bowyer

1
@JakobBowyer Almeno, è bello saperlo! Anche se in questo caso sì, le regex SONO eccessive se alcuni incorporati possono fare lo stesso.
jeromej

8

Il tuo codice non funzionerà; hai bisogno orinvece di ||.

Provare

'0' <= strg[:1] <= '9'

o

strg[:1] in '0123456789'

oppure, se sei davvero pazzo startswith,

strg.startswith(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'))

Ti avrei votato per favore se ci fosse solo la soluzione con startswith (una tupla) . Ma le soluzioni con strg[:1]hanno due inconvenienti: non sollevano un errore se s può capitare di essere un elenco di stringhe e producono True se la stringa inizia con DIVERSE cifre.
eyquem

@eyquem producono True se la stringa inizia con DIVERSE cifre Quindi? Altre risposte non lo controllano, perché non era un requisito che doveva controllare che gli altri caratteri non fossero numerici.
Rob Grant

Io sono pazzo per startswithe ha fatto realizzare in questo modo nel mio codice. Grazie.
jamescampbell

Un altro inizia con possibilità ...startswith(tuple(str(i) for i in range(10)))
Jérôme

6

Sorprendente che dopo così tanto tempo manchi ancora la risposta migliore.

Lo svantaggio delle altre risposte è usare [0]per selezionare il primo carattere, ma come notato, questo si interrompe sulla stringa vuota.

L'uso del seguente aggira questo problema e, a mio parere, fornisce la sintassi più carina e leggibile delle opzioni che abbiamo. Inoltre, non importa / non si preoccupa nemmeno delle espressioni regolari):

>>> string = '1abc'
>>> string[:1].isdigit()
True

>>> string = ''
>>> string[:1].isdigit()
False

4

Questo pezzo di codice:

for s in ("fukushima", "123 is a number", ""):
    print s.ljust(20),  s[0].isdigit() if s else False

stampa quanto segue:

fukushima            False
123 is a number      True
                     False

4
Questo è brutto. Usa s[:1].isdigit()os and s[0].isdigit()
John Machin

1
@ John Machin Cosa intendi per "brutto"? Non leggibile ? Non trovo le tue proposte qui sopra più leggibili. s and s[0].isdigit()è ancora meno leggibile secondo me. Personalmente, mi piace il costrutto ... se ... altrimenti ... Tenendo conto della tua osservazione, lo migliorerei in questo modo:s[0].isdigit() if s!="" else False
eyquem

2

Puoi anche usare try...except:

try:
    int(string[0])
    # do your stuff
except:
    pass # or do your stuff

1

Ecco le mie "risposte" (cercando di essere unico qui, in realtà non lo consiglio neanche per questo caso particolare :-)

Utilizzando ord () ela a <= b <= cforma speciale :

//starts_with_digit = ord('0') <= ord(mystring[0]) <= ord('9')
//I was thinking too much in C. Strings are perfectly comparable.
starts_with_digit = '0' <= mystring[0] <= '9'

(Questo a <= b <= c, come a < b < c, è un costrutto Python speciale ed è abbastanza pulito: confronta 1 < 2 < 3(true) e 1 < 3 < 2(false) e (1 < 3) < 2(true). Non è così che funziona nella maggior parte degli altri linguaggi.)

Utilizzando un'espressione regolare :

import re
//starts_with_digit = re.match(r"^\d", mystring) is not None
//re.match is already anchored
starts_with_digit = re.match(r"\d", mystring) is not None

1
(1) Perdi la ord()(2) Perdi la ^nella regex.
John Machin

0

Potresti usare espressioni regolari .

Puoi rilevare le cifre utilizzando:

if(re.search([0-9], yourstring[:1])):
#do something

Il parametro [0-9] corrisponde a qualsiasi cifra e la tua stringa [: 1] corrisponde al primo carattere della tua stringa



-5

Prova questo:

if string[0] in range(10):

Questo non funziona affatto. range(10)produce un elenco di numeri interi, mentre string[0]è una stringa di lunghezza 1.
Petri Lehtinen

1
Quello non funziona; i tipi non corrispondono. Ma: if string[0] in map(str,range(10))funziona
phynfo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.