# How to take the nth digit of a number in python

Posted on

### Question :

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?

First treat the number like a string

``````number = 9876543210
number = str(number)
``````

Then to get the first digit:

``````number
``````

The fourth digit:

``````number
``````

EDIT:

This will return the digit as a character, not as a number. To convert it back use:

``````int(number)
``````

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.

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)

remaining = num

while remaining := 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')
``````

I would recommend adding a boolean check for the magnitude of the number. I’m converting a high milliseconds value to datetime. I have numbers from 2 to 200,000,200 so 0 is a valid output. The function as @Chris Mueller has it will return 0 even if number is smaller than 10**n.

``````def get_digit(number, n):
return number // 10**n % 10

get_digit(4231, 5)
# 0
``````

``````def get_digit(number, n):
if number - 10**n < 0:
return False
return number // 10**n % 10

get_digit(4321, 5)
# False
``````

You do have to be careful when checking the boolean state of this return value. To allow 0 as a valid return value, you cannot just use `if get_digit:`. You have to use `if get_digit is False:` to keep `0` from behaving as a false value.

I’m very sorry for necro-threading but I wanted to provide a solution without converting the integer to a string. Also I wanted to work with more computer-like thinking so that’s why the answer from Chris Mueller wasn’t good enough for me.

``````import math

def count_number(number):
counter = 0
counter_number = number
while counter_number > 0:
counter_number //= 10
counter += 1
return counter

def digit_selector(number, selected_digit, total):
total_counter = total
calculated_select = total_counter - selected_digit
number_selected = int(number / math.pow(10, calculated_select))
while number_selected > 10:
number_selected -= 10
return number_selected

def main():
x = 1548731588
total_digits = count_number(x)
digit_2 = digit_selector(x, 2, total_digits)
return print(digit_2)

if __name__ == '__main__':
main()
``````

which will print:

``````5
``````

Hopefully someone else might need this specific kind of code. Would love to have feedback on this aswell!

This should find any digit in a integer.

Flaws:

Works pretty ok but if you use this for long numbers then it’ll take more and more time. I think that it would be possible to see if there are multiple thousands etc and then substract those from number_selected but that’s maybe for another time 😉

Usage:

You need every line from 1-21. Then you can call first count_number to make it count your integer.

``````x = 1548731588
total_digits = count_number(x)
``````

Then read/use the digit_selector function as follows:

digit_selector(‘insert your integer here’, ‘which digit do you want to have? (starting from the most left digit as 1)’, ‘How many digits are there in total?’)

If we have 1234567890, and we need 4 selected, that is the 4th digit counting from left so we type ‘4’.

We know how many digits there are due to using total_digits. So that’s pretty easy.

Hope that explains everything!

Han

PS: Special thanks for CodeVsColor for providing the count_number function. I used this link: https://www.codevscolor.com/count-number-digits-number-python to help me make the digit_selector work.

Ok, first of all, use the str() function in python to turn ‘number’ into a string

``````number = 9876543210 #declaring and assigning
number = str(number) #converting
``````

Then get the index, 0 = 1, 4 = 3 in index notation, use int() to turn it back into a number

``````print(int(number)) #printing the int format of the string "number"'s index of 3 or '6'
``````

if you like it in the short form

``````print(int(str(9876543210))) #condensed code lol, also no more variable 'number'
``````

Here’s my take on this problem.

I have defined a function ‘index’ which takes the number and the input index and outputs the digit at the desired index.

The enumerate method operates on the strings, therefore the number is first converted to a string. Since the indexing in Python starts from zero, but the desired functionality requires it to start with 1, therefore a 1 is placed in the enumerate function to indicate the start of the counter.

``````def index(number, i):

for p,num in enumerate(str(number),1):

if p == i:
print(num)
``````