Retornando o último número (script Python)

Meu amigo DGmike publicou: Retornando o último número (script PHP)

Como eu acho interessante comparar soluções em linguagens diferentes, resolvi escrever o mesmo script em Python[bb]. Veja como ficou:

import re
def ultimoNumero(string):
    return re.findall(r"\d+",string)[-1]

Gostou?

Publicado por

Elcio

Elcio é sócio fundador da Visie Padrões Web. Pioneiro no uso e divulgação dos padrões do W3C no Brasil, Elcio já treinou equipes de dezenas de empresas como Globo.com, Terra, Petrobras, iG e Locaweb. Além disso, tem dirigido as equipes da Visie no desenvolvimento de projetos web para marcas como Brastemp, Itaú Unibanco, Johnson & Johnson e Rede Globo.

14 comentários em “Retornando o último número (script Python)”

  1. No meu blog, o junior deu uma solução interessante e eu fiz alguns testes de velocidade (os resultados estão no meu blog). Parece que a solução dele foi melhor, além de ser um pouco mais enxuta. Então eu a adaptei a uma função:

    function ultimo_numero ($string = '')
    {
    if ('string' === gettype ($string))
    {
    return;
    }
    $string = preg_split ( '/[^\d]+/', $string );
    return end ( $string );
    }

    Se retirar esse if, a função sempre retornará uma string (verifiquei isso usando o var_dump() )

  2. ops, esqueci de escapar:

    >>> def ultimo(string):
    … a = re.search(r'(?P<ultimo>\d+)[^\d]*$’, string)
    … return a and a.group(‘ultimo’)

    >>> ultimo(‘dsadasdas22222dddd233’)
    ‘233’
    >>> ultimo(‘dsadasdas22222dddd’)
    ‘22222’
    >>> ultimo(‘1a’)
    ‘1’
    >>> ultimo(‘1a2’)
    ‘2’

  3. gostei mais da sua, mas aqui vai a minha:

    >>> def ultimo(string):
    … a = re.search(r'(?P\d+)[^\d]*$’, string)
    … return a and a.group(‘ultimo’)

    >>> ultimo(‘dsadasdas22222dddd233’)
    ‘233’
    >>> ultimo(‘dsadasdas22222dddd’)
    ‘22222’
    >>> ultimo(‘1a’)
    ‘1’
    >>> ultimo(‘1a2’)
    ‘2’

  4. DGmike, o que eu quis dizer sobre o tratamento do tipo de dados era mais sobre a entrada, que você verificava se o parâmetro passado era string… no retorno não sei se dar um parâmetro opcional vale a pena (em PHP não bastaria um (int)ultimoNum($x)?). Então até por questões de comparação, acho mais justo não colocar isso apenas no PHP, fica injustamente maior quando no fim a linguagem permitiria converter o resultado pra int com a mesma facilidade que as outras 😉

    E aqui uma versão em JavaScript:
    function ultimoNum(string) {
    var match = string.match(/(\d+)\D*$/);
    if (match) {
    return match[1];
    }
    }

    Ela também teve um pequeno toque específico à linguagem: só dei return caso um número seja encontrado, para que caso contrário a função retorne undefined em vez de null ou string em branco, o que me pareceu mais apropriado 🙂 Mas se a briga for por número de linhas de código, dá pra reduzir o return a um condicional como os outros, retornando até mesmo undefined, estando disposto a deixar o código um pouco menos legível pra quem não está habituado à linguagem.

  5. E a versão resumida-filha-da-mae-num-consigo-entender-nada em php.


    function ultimoNum ($s='',$rs=true){
    $s=preg_match_all('\d+',(string) $s,$m);
    $r=end($m[0])?end($m[0]):'';
    if($rs)return (string) $r;
    else return (int) $r;
    }

    Hmmm… como ficaria em javaScript?

  6. Então… a versão em PHP melhorada, com base no que o Daniel disse:

    function ultimo_numero ($string = '', $retornarString = true)
    {
    $string = (string) $string;
    $string = preg_match_all ('(\d+)', $string, $match);
    $return = end($match[0]) ? end($match[0]) : '';
    if ($retornarString)
    {
    return (string) $return;
    } else {
    return (int) $return;
    }
    }

    Meio complexo, mas funciona sempre retornando uma string ou um inteiro, para você poder utilizar como você quiser. Ficou um pouco mais complicada e maior, mas é bem mais completa. 😀

  7. Aliás… uma daquelas soluções que você bate na cabeça e diz “por que não pensei nisso antes?”

    def ultimoNumero(string):
    match = re.search(r'(\d+)\D*$', string)
    return match.group(1) if match else None

    Ou em Ruby:

    def ultimo_numero(string)
    string =~ /(\d+)\D*\Z/ ? $1 : nil
    end

    Mais simples e computacionalmente mais leve 🙂

  8. Uma maneira simples de se resolver a questão é envolver o findall num valor alternativo:
    return (re.findall(…) or [None])[-1]
    (usei None, mas poderia ser trocando por uma string em branco se desejado)

    Ainda falta a questão de verificar o tipo de dados, mas aqui acho interessante comentar: PHP faz conversão implícita de tipos de dados, resultando numa prática bastante comum de passar dados sem convertê-los para o que se realmente deseja (o mais comum, na minha experiência, é tratar strings como se fossem números). Python, por sua vez, nunca faz conversão imlpícita (apenas coerção de tipos numéricos: você pode fazer contas misturando ints e floats, etc), e assim você na prática dificilmente tem em mãos um valor que não é do tipo que se espera. Por isso, acho que numa versão Python o teste do tipo do parâmetro passado é desnecessário. Outro detalhe também é que Python favorece exceções em vez de ignorar erros silenciosamente, então seria até mais “correto” deixar a função findall gerar uma exceção quando o dado passado não for string. 😉

    E pra fins comparativos (também adoro esse tipo de comparação), uma versão equivalente em Ruby:
    def ultimo_numero(string)
    string.scan(/\d+/).pop
    end
    Também retornando nil em caso vazio 🙂

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *