I'm writing a program which calculates the check digit of an ISBN number. I have to read the user's input (nine digits of an ISBN) into an integer variable, and then multiply the last digit by 2, the second last digit by 3 and so on. How can I "split" the integer into its constituent digits to do this? As this is a basic homework exercise I am not supposed to use a list.
15 Answers
Just create a string out of it.
myinteger = 212345
number_string = str(myinteger)
That's enough. Now you can iterate over it:
for ch in number_string:
print ch # will print each digit in order
Or you can slice it:
print number_string[:2] # first two digits
print number_string[-3:] # last three digits
print number_string[3] # forth digit
Or better, don't convert the user's input to an integer (the user types a string)
isbn = raw_input()
for pos, ch in enumerate(reversed(isbn)):
print "%d * %d is %d" % pos + 2, int(ch), int(ch) * (pos + 2)
For more information read a tutorial.

- 217,122
- 57
- 293
- 297
-
This is great. Thank you! – LucCW Jun 30 '17 at 21:16
-
@nosklo Unfortunately Tutorial Url is broken. Do you mind editing ? – M.A.K. Simanto Jul 11 '19 at 10:25
-
when you print digits, you will get an extra 1 at the beginning, how can I solve that? – Pooya Panahandeh Jul 07 '20 at 09:37
while number:
digit = number % 10
# do whatever with digit
# remove last digit from number (as integer)
number //= 10
On each iteration of the loop, it removes the last digit from number, assigning it to digit
.
It's in reverse, starts from the last digit, finishes with the first

- 7,323
- 1
- 30
- 49

- 8,061
- 2
- 34
- 39
-
I added an explanation. If you don't see how it works, take a piece of paper and go through the process step-by-step for a number of choice. – Alexandru Nedelcu Jun 10 '09 at 11:36
-
It extracts the digits from the given number, assuming base 10, starting with the least significant digit. This is a mathematical approach instead of a Pythonic one. An approach that will work in any language. And an approach that will also work when one is interested in the digits of a number written in another base (unlike the other solutions posted here). Hence: +1. – Stephan202 Jun 10 '09 at 11:37
-
this is absolutely insane and is not working in py3k (fix is tiny though) – SilentGhost Jun 10 '09 at 11:42
-
@SilentGhost: the examples above apply int to single characters resulting from iterating over the result of applying str. It is str that returns a base 10 representation of the number. – Stephan202 Jun 10 '09 at 11:58
-
@Stephan202: as it's fairly clear from the question OP starts with a string, so he doesn't need to convert to integer; ISBN is using base 10 digits; if you know the base there are enough buil-in function that let you convert resulting base-10 int to you base-X int. – SilentGhost Jun 10 '09 at 12:20
-
@Alexander: When you can just iterate over the string already entered by the user, instead of converting it to an integer and then doing arithmetic on it. From "Zen of Python": Simple is better than complex. – nosklo Jun 10 '09 at 20:50
-
2
-
4
-
3
list_of_ints = [int(i) for i in str(ISBN)]
Will give you a ordered list of ints. Of course, given duck typing, you might as well work with str(ISBN).
Edit: As mentioned in the comments, this list isn't sorted in the sense of being ascending or descending, but it does have a defined order (sets, dictionaries, etc in python in theory don't, although in practice the order tends to be fairly reliable). If you want to sort it:
list_of_ints.sort()
is your friend. Note that sort() sorts in place (as in, actually changes the order of the existing list) and doesn't return a new list.

- 9,101
- 4
- 34
- 52
-
4
-
-
-
@Daren - not always faster, but usually more readable (excluding reduce() ^^) – uolot Jun 10 '09 at 12:03
-
Sorted in the sense that it has a defined order, as opposed to say a tuple or a set. I'll edit that into the answer... – mavnn Jun 10 '09 at 21:49
-
Yeah, I realised as soon as I submitted it. You'll notice I didn't mention them in the edit. – mavnn Jun 10 '09 at 22:26
On Older versions of Python...
map(int,str(123))
On New Version 3k
list(map(int,str(123)))

- 33,375
- 8
- 89
- 89
-
@Lord British, hard to say, since both are designed for different versions, i'd suppose Py3k should be faster (hopefully,hehe) – st0le Sep 14 '10 at 14:45
(number/10**x)%10
You can use this in a loop, where number is the full number, x is each iteration of the loop (0,1,2,3,...,n) with n being the stop point. x = 0 gives the ones place, x = 1 gives the tens, x = 2 gives the hundreds, and so on. Keep in mind that this will give the value of the digits from right to left, so this might not be the for an ISBN but it will still isolate each digit.

- 63
- 5
Recursion version:
def int_digits(n):
return [n] if n<10 else int_digits(n/10)+[n%10]

- 599
- 5
- 14
Converting to str
is definitely slower then dividing by 10.
map
is sligthly slower than list comprehension:
convert to string with map 2.13599181175
convert to string with list comprehension 1.92812991142
modulo, division, recursive 0.948769807816
modulo, division 0.699964046478
These times were returned by the following code on my laptop:
foo = """\
def foo(limit):
return sorted(set(map(sum, map(lambda x: map(int, list(str(x))), map(lambda x: x * 9, range(limit))))))
foo(%i)
"""
bar = """\
def bar(limit):
return sorted(set([sum([int(i) for i in str(n)]) for n in [k *9 for k in range(limit)]]))
bar(%i)
"""
rac = """\
def digits(n):
return [n] if n<10 else digits(n / 10)+[n %% 10]
def rabbit(limit):
return sorted(set([sum(digits(n)) for n in [k *9 for k in range(limit)]]))
rabbit(%i)
"""
rab = """\
def sum_digits(number):
result = 0
while number:
digit = number %% 10
result += digit
number /= 10
return result
def rabbit(limit):
return sorted(set([sum_digits(n) for n in [k *9 for k in range(limit)]]))
rabbit(%i)
"""
import timeit
print "convert to string with map", timeit.timeit(foo % 100, number=10000)
print "convert to string with list comprehension", timeit.timeit(bar % 100, number=10000)
print "modulo, division, recursive", timeit.timeit(rac % 100, number=10000)
print "modulo, division", timeit.timeit(rab % 100, number=10000)

- 39,470
- 12
- 57
- 97

- 15,669
- 5
- 44
- 68
After own diligent searches I found several solutions, where each has advantages and disadvantages. Use the most suitable for your task.
All examples tested with the CPython 3.5 on the operation system GNU/Linux Debian 8.
Using a recursion
Code
def get_digits_from_left_to_right(number, lst=None):
"""Return digits of an integer excluding the sign."""
if lst is None:
lst = list()
number = abs(number)
if number < 10:
lst.append(number)
return tuple(lst)
get_digits_from_left_to_right(number // 10, lst)
lst.append(number % 10)
return tuple(lst)
Demo
In [121]: get_digits_from_left_to_right(-64517643246567536423)
Out[121]: (6, 4, 5, 1, 7, 6, 4, 3, 2, 4, 6, 5, 6, 7, 5, 3, 6, 4, 2, 3)
In [122]: get_digits_from_left_to_right(0)
Out[122]: (0,)
In [123]: get_digits_from_left_to_right(123012312312321312312312)
Out[123]: (1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 1, 3, 1, 2, 3, 1, 2, 3, 1, 2)
Using the function divmod
Code
def get_digits_from_right_to_left(number):
"""Return digits of an integer excluding the sign."""
number = abs(number)
if number < 10:
return (number, )
lst = list()
while number:
number, digit = divmod(number, 10)
lst.insert(0, digit)
return tuple(lst)
Demo
In [125]: get_digits_from_right_to_left(-3245214012321021213)
Out[125]: (3, 2, 4, 5, 2, 1, 4, 0, 1, 2, 3, 2, 1, 0, 2, 1, 2, 1, 3)
In [126]: get_digits_from_right_to_left(0)
Out[126]: (0,)
In [127]: get_digits_from_right_to_left(9999999999999999)
Out[127]: (9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9)
Using a construction tuple(map(int, str(abs(number)))
In [109]: tuple(map(int, str(abs(-123123123))))
Out[109]: (1, 2, 3, 1, 2, 3, 1, 2, 3)
In [110]: tuple(map(int, str(abs(1412421321312))))
Out[110]: (1, 4, 1, 2, 4, 2, 1, 3, 2, 1, 3, 1, 2)
In [111]: tuple(map(int, str(abs(0))))
Out[111]: (0,)
Using the function re.findall
In [112]: tuple(map(int, re.findall(r'\d', str(1321321312))))
Out[112]: (1, 3, 2, 1, 3, 2, 1, 3, 1, 2)
In [113]: tuple(map(int, re.findall(r'\d', str(-1321321312))))
Out[113]: (1, 3, 2, 1, 3, 2, 1, 3, 1, 2)
In [114]: tuple(map(int, re.findall(r'\d', str(0))))
Out[114]: (0,)
Using the module decimal
In [117]: decimal.Decimal(0).as_tuple().digits
Out[117]: (0,)
In [118]: decimal.Decimal(3441120391321).as_tuple().digits
Out[118]: (3, 4, 4, 1, 1, 2, 0, 3, 9, 1, 3, 2, 1)
In [119]: decimal.Decimal(-3441120391321).as_tuple().digits
Out[119]: (3, 4, 4, 1, 1, 2, 0, 3, 9, 1, 3, 2, 1)

- 4,217
- 2
- 36
- 41
Convert it to string and map over it with the int() function.
map(int, str(1231231231))

- 6,533
- 5
- 58
- 64
Use the body of this loop to do whatever you want to with the digits
for digit in map(int, str(my_number)):

- 505
- 4
- 7
I have made this program and here is the bit of code that actually calculates the check digit in my program
#Get the 10 digit number
number=input("Please enter ISBN number: ")
#Explained below
no11 = (((int(number[0])*11) + (int(number[1])*10) + (int(number[2])*9) + (int(number[3])*8)
+ (int(number[4])*7) + (int(number[5])*6) + (int(number[6])*5) + (int(number[7])*4) +
(int(number[8])*3) + (int(number[9])*2))/11)
#Round to 1 dp
no11 = round(no11, 1)
#explained below
no11 = str(no11).split(".")
#get the remainder and check digit
remainder = no11[1]
no11 = (11 - int(remainder))
#Calculate 11 digit ISBN
print("Correct ISBN number is " + number + str(no11))
Its a long line of code, but it splits the number up, multiplies the digits by the appropriate amount, adds them together and divides them by 11, in one line of code. The .split() function just creates a list (being split at the decimal) so you can take the 2nd item in the list and take that from 11 to find the check digit. This could also be made even more efficient by changing these two lines:
remainder = no11[1]
no11 = (11 - int(remainder))
To this:
no11 = (11 - int(no11[1]))
Hope this helps :)

- 75
- 1
- 1
- 7
Similar to this answer but more a more "pythonic" way to iterate over the digis would be:
while number:
# "pop" the rightmost digit
number, digit = divmod(number, 10)

- 1
- 1

- 26,392
- 13
- 55
- 78
Answer: 165
Method: brute-force! Here is a tiny bit of Python (version 2.7) code to count'em all.
from math import sqrt, floor
is_ps = lambda x: floor(sqrt(x)) ** 2 == x
count = 0
for n in range(1002, 10000, 3):
if n % 11 and is_ps(sum(map(int, str(n)))):
count += 1
print "#%i: %s" % (count, n)

- 289
- 4
- 14
Just assuming you want to get the i-th least significant digit from an integer number x, you can try:
(abs(x)%(10**i))/(10**(i-1))
I hope it helps.

- 402
- 4
- 9
How about a one-liner list of digits...
ldigits = lambda n, l=[]: not n and l or l.insert(0,n%10) or ldigits(n/10,l)

- 405
- 3
- 10