[python] How to split an integer into an array of digits?

My integer input is suppose 12345, I want to split and put it into an array as 1, 2, 3, 4, 5.
How will I be able to do it?

This question is related to python

The answer is


While list(map(int, str(x))) is the Pythonic approach, you can formulate logic to derive digits without any type conversion:

from math import log10

def digitize(x):
    n = int(log10(x))
    for i in range(n, -1, -1):
        factor = 10**i
        k = x // factor
        yield k
        x -= k * factor

res = list(digitize(5243))

[5, 2, 4, 3]

One benefit of a generator is you can feed seamlessly to set, tuple, next, etc, without any additional logic.


Splitting a single number to it's digits (as answered by all):

>>> [int(i) for i in str(12345)]
[1, 2, 3, 4, 5]

But, to get digits from a list of numbers:

>>> [int(d) for d in ''.join(str(x) for x in [12, 34, 5])]
[1, 2, 3, 4, 5]

So like to know, if we can do the above, more efficiently.


Another solution that does not involve converting to/from strings:

from math import log10

def decompose(n):
    if n == 0:
        return [0]
    b = int(log10(n)) + 1
    return [(n // (10 ** i)) % 10 for i in reversed(range(b))]

like @nd says but using the built-in function of int to convert to a different base

>>> [ int(i,16) for i in '0123456789ABCDEF' ]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

>>> [int(i,2) for i in "100 010 110 111".split()]
[4, 2, 6, 7]

I don't know what is the final objective but take a look also inside the decimal module of python for doing stuff like

>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')

I'd rather not turn an integer into a string, so here's the function I use for this:

def digitize(n, base=10):
    if n == 0:
        yield 0
    while n:
        n, d = divmod(n, base)
        yield d

Examples:

tuple(digitize(123456789)) == (9, 8, 7, 6, 5, 4, 3, 2, 1)
tuple(digitize(0b1101110, 2)) == (0, 1, 1, 1, 0, 1, 1)
tuple(digitize(0x123456789ABCDEF, 16)) == (15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

As you can see, this will yield digits from right to left. If you'd like the digits from left to right, you'll need to create a sequence out of it, then reverse it:

reversed(tuple(digitize(x)))

You can also use this function for base conversion as you split the integer. The following example splits a hexadecimal number into binary nibbles as tuples:

import itertools as it
tuple(it.zip_longest(*[digitize(0x123456789ABCDEF, 2)]*4, fillvalue=0)) == ((1, 1, 1, 1), (0, 1, 1, 1), (1, 0, 1, 1), (0, 0, 1, 1), (1, 1, 0, 1), (0, 1, 0, 1), (1, 0, 0, 1), (0, 0, 0, 1), (1, 1, 1, 0), (0, 1, 1, 0), (1, 0, 1, 0), (0, 0, 1, 0), (1, 1, 0, 0), (0, 1, 0, 0), (1, 0, 0, 0))

Note that this method doesn't handle decimals, but could be adapted to.


Maybe join+split:

>>> a=12345
>>> list(map(int,' '.join(str(a)).split()))
[1, 2, 3, 4, 5]
>>> [int(i) for i in ' '.join(str(a)).split()]
[1, 2, 3, 4, 5]
>>> 

str.join + str.split is your friend, also we use map or list comprehension to get a list, (split what we join :-)).


return array as string

>>> list(str(12345))
['1', '2', '3', '4', '5']

return array as integer

>>> map(int,str(12345))
[1, 2, 3, 4, 5]

Strings are just as iterable as arrays, so just convert it to string:

str(12345)

[int(i) for i in str(number)]

or, if do not want to use a list comprehension or you want to use a base different from 10

from __future__ import division # for compatibility of // between Python 2 and 3
def digits(number, base=10):
    assert number >= 0
    if number == 0:
        return [0]
    l = []
    while number > 0:
        l.append(number % base)
        number = number // base
    return l