¿Cómo saber si la cadena comienza con un número con Python?

91

Tengo una cadena que comienza con un número (de 0 a 9) Sé que puedo "o" 10 casos de prueba usando startswith () pero probablemente haya una solución más ordenada

entonces en lugar de escribir

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

¿Existe una forma más inteligente / eficiente?

Ilusionista
fuente
Si se hace la pregunta: "¿Esto es demasiado repetitivo?", Lo más probable es que, en un lenguaje de alto nivel, la respuesta sea "Por qué, sí, seguro que lo es". ¡Ser perezoso!
42
Te perdiste string.startswith('1').
MAK
2
@Illusionist Tal como está escrito, su pregunta significa que desea detectar las cadenas que comienzan con un solo dígito. Si es así, la respuesta sólo la derecha entre los siguientes, no son los que utilizan s[0]o s[:1]sino la solución de John Machin: if s.startswith(tuple('0123456789')). Además, esta solución genera un error cuando sucede que s es una secuencia como una tupla o una lista, cuyos casos producen el mismo resultado que si fuera una cadena. - Otra solución es una expresión regular cuyo patrón es '\ d (? = \ D)' pero el uso de expresiones regulares es superfluo aquí.
eyquem
3
Ser pedante: stringes un módulo en la biblioteca estándar y probablemente no debería usarse como nombre de variable. docs.python.org/2/library/string.html
gak

Respuestas:

170

La stringbiblioteca de Python tiene un isdigit()método:

string[0].isdigit()
plaes
fuente
5
El string módulo de Python2 no tiene métodos y isdigites un método de objetos stry unicode.
John Machin
3
@plaes: -1 debido a lo anterior MÁS se bloquea si s == ""
John Machin
3
Mire mi respuesta que no se rompe por una cadena vacía:string[:1].isdigit()
PascalVKooten
24
>>> string = '1abc'
>>> string[0].isdigit()
True
jcomeau_ictx
fuente
No soy un tipo de pitón, así que tal vez puedas ayudarme con esto: ¿esta función funcionará en "", donde no hay string[0]?
corsiKa
sí, seguro que lo hará. podría usar (cadena o 'x') [0] .isdigit () para arreglarlo para '' o Ninguno
jcomeau_ictx
30
Puede intentarlo string[:1].isdigit(), lo que dejará de tratar felizmente con una cadena vacía.
Simon Callan
2
porque esa no es mi respuesta; el mío es aún mejor en el caso de que el programador desee que se lance una excepción en una cadena vacía.
jcomeau_ictx
1
@jcomeau_ictx exactamente correcto. nunca programe a la defensiva. si la cadena es inesperadamente en blanco, que debe de error y no debe ser manejado de forma automática de todos modos. Algunas escuelas de pensamiento dicen que debe manejar y detectar con gracia las excepciones que no son críticas como advertencia y mantener el programa en marcha. No tengo esta mentalidad para la mayoría de los casos de uso. La especificidad en las funciones y el código que está escribiendo ayuda a mitigar los casos extremos en los que necesitaría codificar de manera defensiva con más frecuencia.
jamescampbell
10

a veces, puedes usar regex

>>> import re
>>> re.search('^\s*[0-9]',"0abc")
<_sre.SRE_Match object at 0xb7722fa8>
Kurumi
fuente
exagerado! ¿Por qué usar re cuando puedes hacerlo en los bultins?
Jakob Bowyer
1
@JakobBowyer ¡Al menos, es bueno saberlo! Aunque en este caso, sí, las expresiones regulares SON exageradas si algunas incorporaciones pueden hacer lo mismo.
jeromej
8

Tu código no funcionará; necesitas en orlugar de ||.

Tratar

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

o

strg[:1] in '0123456789'

o, si está a punto realmente loco startswith,

strg.startswith(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'))
John Machin
fuente
Te habría votado a favor si solo hubiera una solución con startswith (una tupla) . Pero las soluciones strg[:1]tienen dos inconvenientes: no generan un error si s puede resultar ser una lista de cadenas, y producen Verdadero si la cadena comienza con VARIOS dígitos.
eyquem
@eyquem producen True si la cadena comienza con VARIOS dígitos ¿Entonces? Otras respuestas no verifican eso, porque no era un requisito que tuviera que verificar que los otros caracteres no fueran numéricos.
Rob Grant
Yo estoy loco por startswithe hice poner en práctica esta manera en mi código. Gracias.
jamescampbell
Uno más comienzacon posibilidad ...startswith(tuple(str(i) for i in range(10)))
Jérôme
4

Este fragmento de código:

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

imprime lo siguiente:

fukushima            False
123 is a number      True
                     False
eyquem
fuente
4
Eso es feo. Utilice s[:1].isdigit()os and s[0].isdigit()
John Machin
1
@John Machin ¿A qué te refieres con 'feo'? No se puede leer ? No encuentro más legibles sus propuestas aquí arriba. s and s[0].isdigit()es incluso menos legible en mi opinión. Personalmente, me gusta la construcción ... si ... si no ... Teniendo en cuenta su comentario, simplemente lo mejoraría así:s[0].isdigit() if s!="" else False
eyquem
3

Es sorprendente que después de tanto tiempo todavía falte la mejor respuesta.

La desventaja de las otras respuestas es usar [0]para seleccionar el primer carácter, pero como se señaló, esto se rompe en la cadena vacía.

Usar lo siguiente evita este problema y, en mi opinión, proporciona la sintaxis más bonita y legible de las opciones que tenemos. Tampoco importa / molesta con expresiones regulares):

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

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

También puede utilizar try...except:

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

Aquí están mis "respuestas" (tratando de ser único aquí, en realidad no lo recomiendo para este caso en particular :-)

Utilizando ord () yla a <= b <= cforma especial :

//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'

(Esto a <= b <= c, como a < b < c, es una construcción especial de Python y es algo ordenado: compare 1 < 2 < 3(verdadero) y 1 < 3 < 2(falso) y (1 < 3) < 2(verdadero). Así no es como funciona en la mayoría de los otros lenguajes).

Usando una expresión regular :

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

fuente
1
(1) Pierde el ord()(2) Pierde el ^en la expresión regular.
John Machin
0

Podrías usar expresiones regulares .

Puede detectar dígitos usando:

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

El par [0-9] coincide con cualquier dígito y su cadena [: 1] coincide con el primer carácter de su cadena

Tovi7
fuente
-5

Prueba esto:

if string[0] in range(10):
bradley.ayers
fuente
Esto no funciona en absoluto. range(10)produce una lista de números enteros, mientras que string[0]es una cadena de longitud 1.
Petri Lehtinen
1
Eso no funciona; los tipos no coinciden. Pero: if string[0] in map(str,range(10))funciona
phynfo