Inverse of int(s, base)?

Discussion in 'Python' started by olli@secnetix.de, May 10, 2004.

  1. Guest

    Hi,

    Is there an inverse function of int(s, base) where base
    can be any number up to 36? I've searched the library
    reference up and down, but haven't found anything.

    For example, I need to work with base-24 numbers, which
    can be parsed nicely with x = int(s, 24), but there
    doesn't seem to be a way to convert integers back to
    their base-24 representation as a string. (Of course,
    I can define my own function in Python to do that, but
    I wonder if there's a more efficient way.)

    Best regards
    Oliver

    PS: This is what I'm using right now.

    import string
    str_digits = string.digits + string.ascii_lowercase

    def str_base (x, base):
    result = ""
    while x:
    result = str_digits[x % base] + result
    x /= base
    return result or "0"

    >>> print str_base(2065027084, 24)

    aj83kb4
    >>> int("aj83kb4", 24)

    2065027084

    --
    Oliver Fromme, secnetix GmbH & Co KG, Oettingenstr. 2, 80538 M√ľnchen
    Any opinions expressed in this message may be personal to the author
    and may not necessarily reflect the opinions of secnetix in any way.

    "Clear perl code is better than unclear awk code; but NOTHING
    comes close to unclear perl code" (taken from comp.lang.awk FAQ)
    , May 10, 2004
    #1
    1. Advertising

  2. Dan Bishop Guest

    wrote in message news:<>...
    > Hi,
    >
    > Is there an inverse function of int(s, base) where base
    > can be any number up to 36?


    Yes, but for some reason it's not in the Python standard library.

    ....

    > PS: This is what I'm using right now.
    >
    > import string
    > str_digits = string.digits + string.ascii_lowercase
    >
    > def str_base (x, base):
    > result = ""
    > while x:
    > result = str_digits[x % base] + result
    > x /= base


    The above line should be "x //= base", so it works under -Qnew.

    > return result or "0"


    That works (for positive integers), but it might be more efficient to
    not create a new string each time through the loop. An alternative
    is:

    def str_base(n, base=10):
    if n == 0:
    return '0'
    isNegative = n < 0
    if isNegative:
    n = -n
    result = []
    while n > 0:
    n, lastDigit = divmod(n, base)
    result.append(str_digits[lastDigit])
    if isNegative:
    result.append('-')
    result.reverse()
    return ''.join(result)
    Dan Bishop, May 11, 2004
    #2
    1. Advertising

  3. Paul Rubin Guest

    (Dan Bishop) writes:
    > > while x:
    > > result = str_digits[x % base] + result
    > > x /= base

    >
    > The above line should be "x //= base", so it works under -Qnew.


    Or just say:
    x, r = divmod(x, base)
    result = result + str_digits[r]

    > That works (for positive integers), but it might be more efficient to
    > not create a new string each time through the loop. An alternative is:
    >
    > def str_base(n, base=10):

    ...

    Similarly:

    def str_base(n, base=10):
    results = []
    sign,n = ('','-')[n < 0], abs(n)
    while n:
    n, r = divmod(n, base)
    results.append(str_digits[r])
    results.reverse()
    return sign + ''.join(results)
    Paul Rubin, May 11, 2004
    #3
  4. Paul Rubin <http://> wrote:
    > (Dan Bishop) writes:
    > > [...]
    > > That works (for positive integers), but it might be more efficient to
    > > not create a new string each time through the loop. An alternative is:
    > >
    > > def str_base(n, base=10):

    > ...
    >
    > Similarly:
    >
    > def str_base(n, base=10):
    > results = []
    > sign,n = ('','-')[n < 0], abs(n)
    > while n:
    > n, r = divmod(n, base)
    > results.append(str_digits[r])
    > results.reverse()
    > return sign + ''.join(results)


    Cool, thanks both of you! Using divmod() is a good idea.

    Is creating strings really that expensive in Python? I'm
    surpised that you're saying that modifying a list and then
    calling reverse() and join() is more efficient. I thought
    that the overhead of compound objects such as lists is
    more expensive than creating strings, which I thought where
    rather "cheap and simple".

    I work with strings a lot (in scripts for administration,
    CGI programs etc.). And since strings are immutable, I
    often have to create new ones. Now do you suggest I should
    reconsider my approach and rather try to work with lists in
    general, and only convert them back to strings for output
    at the very end?

    Best regards
    Oliver

    --
    Oliver Fromme, secnetix GmbH & Co KG, Oettingenstr. 2, 80538 Munich
    Any opinions expressed in this message may be personal to the author
    and may not necessarily reflect the opinions of secnetix in any way.

    (On the statement print "42 monkeys" + "1 snake":) By the way,
    both perl and Python get this wrong. Perl gives 43 and Python
    gives "42 monkeys1 snake", when the answer is clearly "41 monkeys
    and 1 fat snake". -- Jim Fulton
    Oliver Fromme, May 11, 2004
    #4
  5. > Is there an inverse function of int(s, base) where base
    > can be any number up to 36?


    How about this?

    )esab ,s(tni

    :)
    Andrew Koenig, May 11, 2004
    #5
  6. Paul Rubin Guest

    Oliver Fromme <> writes:
    > Is creating strings really that expensive in Python? I'm
    > surpised that you're saying that modifying a list and then
    > calling reverse() and join() is more efficient. I thought
    > that the overhead of compound objects such as lists is
    > more expensive than creating strings, which I thought where
    > rather "cheap and simple".


    Actually, for these int conversions (unless they're large long ints)
    it's no big deal. The concern is when you're building up a long
    string (say, a 10 kilobyte html page) by concatenating a lot of short
    strings. When you say "a = a + b" the cost is proportional to
    len(a+b), since that many chars must get copied around. In the
    extreme case, suppose you build up a 10k web page one character at a
    time:

    for c in get_next_char():
    page = page + c

    The first iteration copies 1 character, the next iteration copies 2
    chars, the next one 3 chars, etc. So the total amount of copying is
    1+2+3+...+10000, which is around 50 million. In general it's O(N**2)
    where N is the number of concatenations.

    By comparison, when you append something to a list, the cost is
    usually constant. There's extra space in the list for appending, so
    nothing gets copied (if there's no extra space left, then stuff does
    get copied and more space is allocated). So
    for c in get_next_char():
    page.append(c)
    is much more efficient than string concatenation. At the end, you do
    all the concatenation in one step with ''.join(page).

    See also the StringIO and cStringIO library modules for possibly
    preferable ways to do this.
    Paul Rubin, May 11, 2004
    #6
  7. Steve Guest

    Paul Rubin wrote:
    > Oliver Fromme <> writes:
    >
    >>Is creating strings really that expensive in Python? I'm
    >>surpised that you're saying that modifying a list and then
    >>calling reverse() and join() is more efficient. I thought
    >>that the overhead of compound objects such as lists is
    >>more expensive than creating strings, which I thought where
    >>rather "cheap and simple".

    >
    >
    > Actually, for these int conversions (unless they're large long ints)
    > it's no big deal. The concern is when you're building up a long
    > string (say, a 10 kilobyte html page) by concatenating a lot of short
    > strings. When you say "a = a + b" the cost is proportional to
    > len(a+b), since that many chars must get copied around. In the
    > extreme case, suppose you build up a 10k web page one character at a
    > time:

    [snip]

    This is a good time to remind newbies that the root of
    all evil lies in premature optimization (attributed to
    Donald Knuth).

    You could do worse than read Guido's anecdote:
    http://www.python.org/doc/essays/list2str.html

    Then, read Joel's discussion of "Shlemiel the painter's
    algorithm":
    http://www.joelonsoftware.com/articles/fog0000000319.html

    And an example of it here:
    http://lambda.weblogs.com/discuss/msgReader$3130
    (see one of the last reader's comments)

    In conclusion: if you are absolutely positive that you
    are only going to be adding together a few short
    strings, then you gain much readability by just adding
    together short strings. But if you are going to be
    adding together lots of long strings, use lists and
    only convert to a string at the end.

    --
    Steven D'Aprano
    Steve, May 12, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Schnoffos
    Replies:
    2
    Views:
    1,195
    Martien Verbruggen
    Jun 27, 2003
  2. Hal Styli
    Replies:
    14
    Views:
    1,612
    Old Wolf
    Jan 20, 2004
  3. arun
    Replies:
    8
    Views:
    430
    Dave Thompson
    Jul 31, 2006
  4. aling
    Replies:
    8
    Views:
    931
    Jim Langston
    Oct 20, 2005
  5. Replies:
    9
    Views:
    417
    James Kanze
    Apr 17, 2007
Loading...

Share This Page