Reverse Iteration Through Integers

B

Benjamin Middaugh

I'm trying to make an integer that is the reverse of an existing integer
such that 169 becomes 961. I guess I don't know enough yet to figure out
how to do this without a ton of awkward-looking code. I've tried for
loops without much success. I guess I need a good way of figuring out
the length of the input integer so my loop can iterate that many times
to reverse the number, but I keep getting errors that say "TypeError:
'Int' object is not iterable".

Any help would be much appreciated,

Benjamin "Self-Proclaimed Python Newbie"
 
L

Lie Ryan

Benjamin said:
I'm trying to make an integer that is the reverse of an existing integer
such that 169 becomes 961. I guess I don't know enough yet to figure out
how to do this without a ton of awkward-looking code. I've tried for
loops without much success. I guess I need a good way of figuring out
the length of the input integer so my loop can iterate that many times
to reverse the number, but I keep getting errors that say "TypeError:
'Int' object is not iterable".

Any help would be much appreciated,

Benjamin "Self-Proclaimed Python Newbie"

you need to turn the int to a str:
 
P

Paul Rubin

Benjamin Middaugh said:
I'm trying to make an integer that is the reverse of an existing
integer such that 169 becomes 961. I guess I don't know enough yet to
figure out how to do this without a ton of awkward-looking code. I've
tried for loops without much success. I guess I need a good way of
figuring out the length of the input integer so my loop can iterate
that many times to reverse the number, but I keep getting errors that
say "TypeError: 'Int' object is not iterable".

Sounds like you're working on Euler problems ;-).

The simplest way is to turn the integer to a string:
n_int = 961
n_string = str(n_int)

then reverse the string:

n_string_reversed = reversed(n_string)

and turn it back into an int:

n_int_reversed = int(n_string_reversed)

If you want to peel off digits from an int one by one without string
conversions, it's easiest to do that in reverse order:

n = 961
digits = []
while n > 0:
n,d = divmod(n, 10)
digits.append(d)

Look up the docs for "divmod" for an explanation of that handy function.
Now the above gives you a reversed list of digits--what to do with it
is an exercise for you ;-). Note that if n=0 then you get the empty list.

Yet another way is to use recursion. I'll leave that as an exercise too.
 
M

Mick Krippendorf

Paul said:
Yet another way is to use recursion. I'll leave that as an exercise too.

This time with big numbers:


def trampoline(bouncing, *args, **kwargs):
while bouncing:
result, bouncing, args, kwargs = bouncing(*args, **kwargs)
if result:
return result()

def bouncy(function):
return lambda *args, **kwargs:(None, function, args, kwargs)

def land(result=None):
return lambda:result, None, None, None


def reverse(n):
@bouncy
def rev(i=n, j=0, k=0):
if i:
return rev(*divmod(i, 10), k=(j+k)*10)
return land(j + k)
return trampoline(rev)


print reverse(169883903200298309284038223098439430943092816286 ** 123)


Try it without the @bouncy decoration.

Granted, the code looks like a serious case of Haskell envy, but after
recursion and tail call optimization being cryptic was just the logical
consequence ;-)

Mick.
 
B

Bearophile

Paul Rubin:
If you want to peel off digits from an int one by one without string
conversions, it's easiest to do that in reverse order:

  n = 961
  digits = []
  while n > 0:
    n,d = divmod(n, 10)
    digits.append(d)

Look up the docs for "divmod" for an explanation of that handy function.
Now the above gives you a reversed list of digits--what to do with it
is an exercise for you ;-).  Note that if n=0 then you get the empty list.

I think that with Psyco it's better to avoid divmod().

It's very positive to teach novices to always use tests every time
they write a function, because it makes their programs less buggy and
often allows them to solve the whole programming problem sooner:


def reverse(n):
"""
Reverse the digits of integer n, ignoring trailing zeros.
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for divmod(): 'str' and
'int'
>>> [reverse(x) for x in (0, 1, -1, 2, -2L, 100L, -100)] [0, 1, -1, 2, -2L, 1L, -1]
>>> [reverse(x) for x in (125, 1250, 123456789)] [521, 521, 987654321]
>>> [reverse(x) for x in (0.0, 1.0, -5.3, 125.0, 1.23456e20)] [0, 1.0, -5.2999999999999998, 521.0, 654321.0]
>>> str(reverse(169883903200298309284038223098439430943092816286
** 123))[:35]
'65852401624276201339740994895755844'
"""
# code removed ...

if __name__ == "__main__":
import doctest
doctest.testmod()
print "Doctests done"


Using tests (and a bit later to use a versioning system) is among the
things that have to be taught as soon as possible :)

Bye,
bearophile
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,294
Messages
2,571,511
Members
48,213
Latest member
DonnellTol

Latest Threads

Top