How to take the nth digit of a number in python

前端 未结 7 1462
梦毁少年i
梦毁少年i 2020-11-30 10:42

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

相关标签:
7条回答
  • 2020-11-30 11:12

    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])
    
    0 讨论(0)
  • 2020-11-30 11:13

    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)
    
    0 讨论(0)
  • 2020-11-30 11:14

    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[3])) #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)[3])) #condensed code lol, also no more variable 'number'
    
    0 讨论(0)
  • 2020-11-30 11:15

    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 10000000 tests run with a max number size less than 10000000000000000000000000000.

    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')
    
    0 讨论(0)
  • 2020-11-30 11:21

    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.

    0 讨论(0)
  • 2020-11-30 11:26

    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.

    0 讨论(0)
提交回复
热议问题