0
votes

Description of problem

I need to get the first number from a given integer. This operation will be done millions of times, therefore I need to make sure that I use the most efficient way of doing this.

If the length of the integer affects the answer, then in my case I know that the integer will always be a 2 digit number.

What I tried

I have tried the methods mentioned below. Method 1 and 2 seems slow since I have to convert back and forth. Method 3 uses //, ** and % which I could assume are also heavy on the system. Is there a better way of performing this seemingly "simple" task?

# Method 1:
first_digit = int(str(x)[0])

# Method 2:
first_digit = int(str(x)[1:])

# Method 3:
first_digit = x // 10 % 10
2
if doing this millions of times might be better to use numpy over vanilla pythonUmar.H
Did you try and do any timing of these different options? Are you sure that this will be a bottleneck in whatever you're going to use it, and that you're not trying to prematurely optimize?Thierry Lathuille
Have you actually timed a million such operations?Abhinav Mathur
I tried to time it now with the functions separated and it runs for a long time. But when I get the actually numbers out it says 0.0 which is weird. However, I tried using cProfile and then it told me that the operator int(str(x)[1:]) was amongst the 5 largest time consumers of my code, therefore my question.eligolf
I advise you to give a look to stackoverflow.com/questions/5558492/… if you plan to use Numpy, Numba, Cython or PyPy.Jérôme Richard

2 Answers

2
votes

If the number has never more than 2 digits the % 10 is useless. But could it have a single digit as well ? In that case the result would be zero which is wrong. So, assumed that the number is never more than 2 digits, the formula could be :

if x > 9: 
    return x // 10;
return x
2
votes

I used timeit module to time your methods as well as dspr's on 10 million repeats :

from timeit import timeit

n = 10000000
print(timeit(stmt='import random; n = random.randint(10, 99); x = int(str(n)[0])', number=n))
print(timeit(stmt='import random; n = random.randint(10, 99); x = int(str(n)[1:])', number=n))
print(timeit(stmt='import random; n = random.randint(10, 99); x = n // 10 % 10', number=n))
print(timeit(stmt='import random; n = random.randint(10, 99); x = n//10 if n>9 else n', number=n))

which gave me the following results :

10.7325472
11.0877854
8.493264900000003
8.550117300000004

It seems that x // 10 % 10 method is a little bit faster than the others.