Como saber se a string começa com um número com Python?


95

Eu tenho uma string que começa com um número (de 0-9) Eu sei que posso "ou" 10 casos de teste usando startswith () mas provavelmente há uma solução mais limpa

então ao invés de escrever

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 uma maneira mais inteligente / eficiente?


Se a pergunta for: "Isso é muito repetitivo?", As chances são - em uma linguagem de alto nível - a resposta é "Por que, sim, com certeza é". Ser preguiçoso!

42
Você errou string.startswith('1').
— MAK,

2
@Illusionist Como está escrito, sua pergunta significa que você deseja detectar as strings que começam com apenas UM dígito. Se assim for, a resposta só direito entre as seguintes, não são os que utilizam s[0]ou s[:1]Mas a solução de John Machin: if s.startswith(tuple('0123456789')). Além disso, essa solução gera erro quando acontece que s é uma sequência como uma tupla ou lista, cujos casos produzem o mesmo resultado que se fosse uma string. - Outra solução é uma regex cujo padrão é '\ d (? = \ D)', mas o uso de regex é supérfluo aqui.
— eyquem de

3
Apenas sendo pedante: stringé um módulo da biblioteca padrão e provavelmente não deve ser usado como um nome de variável. docs.python.org/2/library/string.html
— gak

Respostas:


177

A stringbiblioteca do Python tem isdigit()método:

string[0].isdigit()

5
O string módulo do Python2 não tem métodos e isdigité um método de stre unicodeobjetos.
— John Machin,

3
@plaes: -1 por causa do acima MAIS ele trava se s == ""
— John Machin

4
Veja minha resposta, que não se string[:1].isdigit()
— divide

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

Eu não sou um cara do python, então talvez você possa me ajudar nisso: essa função bombará em "", onde não há string[0]?
— corsiKa,

sim, com certeza vai. você pode usar (string ou 'x') [0] .isdigit () para corrigi-lo para '' ou nenhum
— jcomeau_ictx

30
Você pode tentar string[:1].isdigit(), o que não deixará de lidar com uma string vazia.
— Simon Callan,

2
porque essa não é minha resposta; o meu é ainda melhor no caso em que o programador deseja que uma exceção seja lançada em uma string vazia.
— jcomeau_ictx

1
@jcomeau_ictx exatamente certo. nunca programe defensivamente. se a string estiver inesperadamente em branco, isso deve ocorrer em erro e não deve ser tratado automaticamente de qualquer maneira. Algumas escolas de pensamento dizem que você deve lidar com e capturar exceções que não são críticas como advertência e manter o programa funcionando. Não tenho essa mentalidade para a maioria dos casos de uso. A especificidade nas funções e no código que você está escrevendo ajuda a mitigar os casos extremos em que você precisaria codificar defensivamente com mais frequência.
— jamescampbell

10

às vezes, você pode usar regex

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

exagero! Por que usar fogo quando você pode fazer isso nos bultins
— Jakob Bowyer,

1
@JakobBowyer Pelo menos, é bom saber disso! Mesmo que neste caso, sim, regexes SÃO um exagero se alguns builtins podem fazer o mesmo.
— jeromej

8

Seu código não funcionará; você precisa em orvez de ||.

Experimentar

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

ou

strg[:1] in '0123456789'

ou, se você é realmente louco por startswith,

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

Eu teria votado contra você se houvesse apenas a solução com startswith (uma tupla) . Mas as soluções com strg[:1]têm dois inconvenientes: não geram um erro se s for uma lista de strings e produzem True se a string começar com VÁRIOS dígitos.
— eyquem de

@eyquem eles produzem True se a string começar com VÁRIOS dígitos. Então? Outras respostas não verificam isso, porque não era um requisito que ele tivesse que verificar se os outros caracteres não eram numéricos.
— Rob Grant,

Eu sou louco por isso startswithe implementei dessa forma em meu código. Obrigado.
— jamescampbell

Mais uma partida com possibilidade ...startswith(tuple(str(i) for i in range(10)))
— Jérôme

6

É surpreendente que depois de tanto tempo ainda falte a melhor resposta.

A desvantagem das outras respostas é usar [0]para selecionar o primeiro caractere, mas, como observado, isso quebra na string vazia.

Usar o seguinte contorna esse problema e, na minha opinião, fornece a sintaxe mais bonita e legível das opções que temos. Também não importa / incomoda com regex):

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

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

4

Este trecho de código:

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

imprime o seguinte:

fukushima            False
123 is a number      True
                     False

4
Isso é feio. Use s[:1].isdigit()ous and s[0].isdigit()
— John Machin de

1
@John Machin O que você quer dizer com 'feio'? Ilegível ? Não acho suas proposições aqui acima mais legíveis. s and s[0].isdigit()é ainda menos legível na minha opinião. Pessoalmente, gosto da construção ... if ... else ... Levando em consideração sua observação, gostaria apenas de melhorá-la assim:s[0].isdigit() if s!="" else False
— eyquem

2

Você também pode usar try...except:

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

1

Aqui estão minhas "respostas" (tentando ser único aqui, eu realmente não recomendo para este caso em particular :-)

Usando ord () eo a <= b <= cformulário 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'

(Isso a <= b <= c, como a < b < c, é uma construção especial do Python e é bem legal: compare 1 < 2 < 3(verdadeiro) e 1 < 3 < 2(falso) e (1 < 3) < 2(verdadeiro). Não é assim que funciona na maioria das outras linguagens.)

Usando uma expressão 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

1
(1) Perder o ord()(2) Perder o ^na regex.
— John Machin,

0

Você pode usar expressões regulares .

Você pode detectar dígitos usando:

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

O par [0-9] corresponde a qualquer dígito, e sua string [: 1] corresponde ao primeiro caractere de sua string



-5

Experimente isto:

if string[0] in range(10):

Isso não funciona de jeito nenhum. range(10)produz uma lista de inteiros, enquanto string[0]é uma string de comprimento 1.
— Petri Lehtinen,

1
Isso não funciona; os tipos não combinam. Mas: if string[0] in map(str,range(10))funciona
— phynfo,
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.