How to take the nth digit of a number in python
I want to take the nth digit from an N digit number in python. For example:
number = 9876543210
i = 4
number[i] # should return 6
How can I do something like that in python? Should I change it to string first and then change it to int for the calculation?
You can do it with integer division and remainder methods
def get_digit(number, n):
return number // 10**n % 10
get_digit(987654321, 0)
# 1
get_digit(987654321, 5)
# 6
The //
performs integer division by a power of ten to move the digit to the ones position, then the %
gets the remainder after division by 10. Note that the numbering in this scheme uses zero-indexing and starts from the right side of the number.
First treat the number like a string
number = 9876543210
number = str(number)
Then to get the first digit:
number[0]
The fourth digit:
number[3]
EDIT:
This will return the digit as a character, not as a number. To convert it back use:
int(number[0])
I was curious about the relative speed of the two popular approaches - casting to string and using modular arithmetic - so I profiled them and was surprised to see how close they were in terms of performance.
(My use-case was slightly different, I wanted to get all digits in the number.)
The string approach gave:
10000002 function calls in 1.113 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
10000000 1.113 0.000 1.113 0.000 sandbox.py:1(get_digits_str)
1 0.000 0.000 0.000 0.000 cProfile.py:133(__exit__)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
While the modular arithmetic approach gave:
10000002 function calls in 1.102 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
10000000 1.102 0.000 1.102 0.000 sandbox.py:6(get_digits_mod)
1 0.000 0.000 0.000 0.000 cProfile.py:133(__exit__)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
There were 10^7 tests run with a max number size less than 10^28.
Code used for reference:
def get_digits_str(num):
for n_str in str(num):
yield int(n_str)
def get_digits_mod(num, radix=10):
remaining = num
yield remaining % radix
while remaining := remaining // radix:
yield remaining % radix
if __name__ == '__main__':
import cProfile
import random
random_inputs = [random.randrange(0, 10000000000000000000000000000) for _ in range(10000000)]
with cProfile.Profile() as str_profiler:
for rand_num in random_inputs:
get_digits_str(rand_num)
str_profiler.print_stats(sort='cumtime')
with cProfile.Profile() as mod_profiler:
for rand_num in random_inputs:
get_digits_mod(rand_num)
mod_profiler.print_stats(sort='cumtime')