newbie str to int

Alex Martelli aleax at aleax.it
Thu Dec 6 10:08:05 EST 2001


"Wojtek Walczak" <gminick at hacker.pl> wrote in message
news:slrna0ppdm.ck.gminick at hannibal.localdomain...
> Dnia Wed, 03 Oct 2001 23:11:00 GMT, Andrei Kulakov napisa³(a):
> >On Tue, 2 Oct 2001 12:22:29 +0800, James <no at email.com> wrote:
> >> I am switching from Perl to Python, and would
> >> like to convert string '123abc' to integer 123.
> >> foo = int('123abc') # error
> >> foo = string.atoi('123abc') #error
> >> foo = eval('123abc') # error
> >import string
> >lst = ""
> >for char in "123abc":
> >    if char in string.digits:
> >        lst += char
> >    else:
> >        break
> >num = int(lst)
> or sth like that:
>
> a = '123abc456gfh'
> b = []
>
> for i in a:
>    if i.isdigit():
>    b = b +i
> print b # 123456

This doesn't reproduce Perl behavior (Perl would take this
string as worth 123, not 123456).  Anyway, if yours is the
behavior that is indeed required, rather than Perl's, then
a very fast alternative might be:

import string
no_translation = string.maketrans('', '')
non_digits = string.translate(no_translation, no_translation, string.digits)

def ww_string_to_int(astring):
    return int('0'+string.translate(astring, no_translation, non_digits))


As seems to be most often the case in my usage of the speedy
string.translate function, I don't really want any translation;
rather, I use the 'deletion' ability of the function.

string.translate(s, table, deletechars) returns a copy of s
[if you pass as 'table' a don't-translate table, like here],
without the characters found in the string passed as argument
deletechars.  So, the first call to string.translate, used
during module initialization, is actually getting the complement
of string.digits (since the table no_translation is a string
of all 256 1-byte characters); the second call, inside
function ww_string_to_int, is removing non-digits, i.e.,
keeping only the digits.  I prepend a '0' to make sure a
string containing no digits at all evaluates to 0 (you could
alternatively do this with a try-except, of course).


If the original poster needs the *prefix* of the string made
up of digits, unfortunately there is no such direct support
in the string module.  Using the re module and a regular
expression such as r'^(\d+)' is one obvious possibility, but
if one must avoid re's then one has to code something like:

def op_string_to_int(astring):
    for i in range(len(astring)):
        if not astring[i].isdigit():
            return int('0'+astring[:i])
    return int('0'+astring)


Alex






More information about the Python-list mailing list