473,385 Members | 1,396 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Fastest way to loop through each digit in a number?

Hi,
If I have a lot of integers and want do something with each digit as
integer, what is the fastest way to get there?

Eg. Make 12345 into an iterable object, like [1,2,3,4,5] or "12345"

(Btw: What is the English term for this process; itemize? tokenize?
digitize? sequence?)

Some examples:

n = 12345

#1.
s = str(n)
for i in s:
d = int(i)
foo(d)

#2.
nl = map(int, str(n))
for d in nl:
foo(d)

#3.
nl = [int(x) for x in str(n)]
for d in nl:
foo(d)

Of those, I have, a bit surprised, found that #1 is the fastest, and
that #2 using map() is faster than #3 using list comprehension. I also
registered that that repr(n) is about 8% faster than str(n).

Are there faster ways? Is it possible to avoid casting types?

Thanks for all answers!

Jul 18 '05 #1
9 32473
In article <ss********************************@4ax.com>,
Rune Strand <rst@_nospam_.drlug.org._nospam_> wrote:
Hi,
If I have a lot of integers and want do something with each digit as
integer, what is the fastest way to get there?

Eg. Make 12345 into an iterable object, like [1,2,3,4,5] or "12345"


Does it matter what order you process the digits, i.e. least-significant
first vs. most-significant first? If you can do least first, then you
might be best off doing something straight-forward like:

i = 12345
while i:
digit = i % 10
i = i / 10
print digit

although, with the new-style division, I'm not sure if you want / or //.
Jul 18 '05 #2
Rune Strand <rst@_nospam_.drlug.org._nospam_> writes:
You could try timing something like

while n:
n,d = divmod(n, 10)
foo(d)

That processes the digits in reverse order, of course.
Jul 18 '05 #3
Paul Rubin <http://ph****@NOSPAM.invalid> wrote:
You could try timing something like

while n:
n,d = divmod(n, 10)
foo(d)

That processes the digits in reverse order, of course.


Thanks!
It's faster! But Roy Smiths modulus (%) method is even faster. The
order does matter, but even when appending d to a list inside the loop
and reversing it when done, your methods are faster than my initial
groks ;-)
Jul 18 '05 #4

"Rune Strand" <rst@_nospam_.drlug.org._nospam_> wrote in message
news:ss********************************@4ax.com...
Hi,
If I have a lot of integers and want do something with each digit as
integer, what is the fastest way to get there?

Eg. Make 12345 into an iterable object, like [1,2,3,4,5] or "12345"

(Btw: What is the English term for this process; itemize? tokenize?
digitize? sequence?)

Some examples:

You might also look at

zero = ord('0')

and then ord(i)-zero in loop

tjr

Jul 18 '05 #5
n2 = n
while n2 > 0:
d = n2 % 10
n2 /= 10
foo(d)
Jul 18 '05 #6
Roy Smith <ro*@panix.com> wrote:
In article <ss********************************@4ax.com>,
Rune Strand <rst@_nospam_.drlug.org._nospam_> wrote:
Hi,
If I have a lot of integers and want do something with each digit as
integer, what is the fastest way to get there?

Eg. Make 12345 into an iterable object, like [1,2,3,4,5] or "12345"


Does it matter what order you process the digits, i.e. least-significant
first vs. most-significant first? If you can do least first, then you
might be best off doing something straight-forward like:

i = 12345
while i:
digit = i % 10
i = i / 10
print digit

although, with the new-style division, I'm not sure if you want / or //.


He'd surely want truncation, so I don't understand why he could possibly
want / (which in new-style division means true, non-truncating
division), it's surely gotta be //. divmod looks like it might be
better, but from some q&d timeit.py'ing, it seems this approach is
fastest (30% faster than divmod) if these semantics are OK (when i is 0
you get nothing rather than a single 0...) -- map(int, str(i)) is midway
in speed through these purely numeric approaches (with % and // vs with
divmod).
Alex

Jul 18 '05 #7
On Mon, 6 Sep 2004 02:32:46 -0400, "Terry Reedy" <tj*****@udel.edu>
wrote:
You might also look at

zero = ord('0')

and then ord(i)-zero in loop


Thanks! That seems like the fastest solution.
When looping through 1000000, I get these results:
ord : 4.703 (Terry Reedy)
divmod : 10.469 (Paul Rubin)
modulo : 7.625 (Roy Smith)
lst comp: 11.750
map : 9.062
str : 8.219

The modulo and divmod methods includes list.append(d) and
list.reverse() (list.append mapped to list_append).

Jul 18 '05 #8
;-) Somtimes the solition is too obvious... faster than using ord()
is to look up the value in a map:

dictmap = {
'0' : 0,
'1' : 1,
'2' : 2,
'3' : 3,
'4' : 4,
'5' : 5,
'6' : 6,
'7' : 7,
'8' : 8,
'9' : 9
}

def each_dig_in_num(n):
dm = dictmap #faster if local
s = repr(n) #repr is faster than str
for char in s:
foo(dm[char])

Jul 18 '05 #9
On Mon, 06 Sep 2004 04:56:54 +0200, Rune Strand <rst@_nospam_.drlug.org._nospam_> wrote:
Hi,
If I have a lot of integers and want do something with each digit as
integer, what is the fastest way to get there?
How many is "a lot" ? And what are the bounds on your integers' values? ;-)
Keep in mind that whatever you are computing, it is a mapping from imput to output,
and sometimes it pays to implement a subproblem literally as a mapping.
Eg. Make 12345 into an iterable object, like [1,2,3,4,5] or "12345"
E.g., if you had a bazillion numbers that were all positive and five digits max,
then your fastest mapping from number to digit sequence would probably be a precomputed
list or tuple with data like (untested):

digitseqs = [[0],[1],[2],...[8],[9],[1,0],[1,1],[1,2]... [1,2,3,4,5],[1,2,3,4,6], ... [9,9,9,9,9]]

and then there would be no computation of the digits in

for d in digitseqs[number]:
foo(d)

If your numbers are bigger, you can still use the same technique, chunkwise, e.g.,
if you know you have positive 32-bit integers, that's 0<= number <= 1073741824

if number >= 1000000000:
foo(1)
number -= 1000000000
low5 = number % 100000
for d in digitseqs[number//100000]: foo(d)
for d in zdigitseqs[low5]: foo(d)

(zdigitseqs are all 5-digit sequences with leading zeroes included, [[0,0,0,0,0],[0,0,0,0,1], ...])

If your numbers are unbounded, you can still do something along these lines, but
numbers have to be _huge_ before you gain more than you lose in complication.
You could wrap the above in a function like def fooit(number, foo=foofunc): ...
but calls are relatively expensive in time, so you may want to forego the nicer style.

Obviously 100k lists of lists take a fair chunk of memory, and take a little time to
pre-compute, but it may pay off if you have REALLY "a lot" of input numbers ;-)

(Btw: What is the English term for this process; itemize? tokenize?
digitize? sequence?)

Some examples:

n = 12345

#1.
s = str(n)
for i in s:
d = int(i)
foo(d)

#2.
nl = map(int, str(n))
for d in nl:
foo(d)

#3.
nl = [int(x) for x in str(n)]
for d in nl:
foo(d)

Of those, I have, a bit surprised, found that #1 is the fastest, and
that #2 using map() is faster than #3 using list comprehension. I also
registered that that repr(n) is about 8% faster than str(n).

Are there faster ways? Is it possible to avoid casting types?

Thanks for all answers!

I haven't timed the above (or even tested it), but your gains (if any ;-) will depend on
what you can assume about your input data.

Regards,
Bengt Richter
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: David P. Jessup | last post by:
Well I have seen this posted before and haven't seen much in response. My application has to browse through various folders and find file names. Sometimes these folders can have thousands of...
8
by: Hardrock | last post by:
I encountered some difficulty in implementing dynamic loop nesting. I.e. the number of nesting in a for(...) loop is determined at run time. For example void f(int n) { For(i=0; i<=K; i++)...
10
by: zahy[dot]bnaya[At]gmail[dot]com | last post by:
Hello all, Sorry for the stupid question, It's probably has a simple solution but I'm stuck on this for quite a while... I have this piece of code, I've numbered it for clarification. As far as...
30
by: Chaos | last post by:
As my first attempt to loop through every pixel of an image, I used for thisY in range(0, thisHeight): for thisX in range(0, thisWidth): #Actions here for Pixel thisX, thisY But it takes...
5
by: eyoung | last post by:
I have a function to check a string to make sure it is 6 digites using the trigger onBlur="CkFrmt(this)" Problem is I've got 4 fields in a row...if I enter a wrong number in the first and hit tab...
8
by: Candace | last post by:
I am using the following code to pick off each digit of a number, from right to left. The number I am working with is 84357. So for the first iteration it should return the number 7 and for the...
52
by: MP | last post by:
Hi trying to begin to learn database using vb6, ado/adox, mdb format, sql (not using access...just mdb format via ado) i need to group the values of multiple fields - get their possible...
2
by: hikmaz | last post by:
I am trying to get the rightmost digits (%10) of a number (taken from the user) and store it into successive array locations and get rid of the rightmost digit (\10) to store the next and so on and...
12
by: beatjunkie27 | last post by:
I am working on a class assignment called Pennies for Pay the object of the program is to receive input for number of days worked. This should be > 0 and <= 40. An example output is below and...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.