将一个整数分成数字来计算一个ISBN校验和

我在写一个计算一个ISBN号的校验位的程序。 我必须读取用户的input(一个ISBN的九位数字)为一个整数variables,然后乘以最后一位数字2,最后一位数字乘以3,依此类推。 我怎样才能“分裂”整数成其组成数字来做到这一点? 由于这是一个基本的家庭作业,我不应该使用一个列表。

只要创build一个string。

myinteger = 212345 number_string = str(myinteger) 

这就够了。 现在你可以遍历它了:

 for ch in number_string: print ch # will print each digit in order 

或者你可以切片:

 print number_string[:2] # first two digits print number_string[-3:] # last three digits print number_string[3] # forth digit 

或者更好的是,不要把用户的input转换成一个整数(用户键入一个string)

 isbn = raw_input() for pos, ch in enumerate(reversed(isbn)): print "%d * %d is %d" % pos + 2, int(ch), int(ch) * (pos + 2) 

欲了解更多信息阅读教程 。

 while number: digit = number % 10 # do whatever with digit # remove last digit from number (as integer) number //= 10 

在循环的每次迭代中,它将从数字中删除最后一位数字,并将其分配给digit 。 它是相反的,从最后一位开始,与第一位完成

 list_of_ints = [int(i) for i in str(ISBN)] 

会给你一个有序的整数列表。 当然,给鸭子打字,你也可以使用str(ISBN)。

编辑:正如在评论中提到的,这个列表不是按升序或降序的意思sorting的,但是它确实有一个确定的顺序(Python中的集合,字典等在理论上不是这样,尽pipe在实践中顺序趋向于相当可靠)。 如果你想sorting:

list_of_ints.sort()

是你的朋友。 请注意,sort()就地sorting(如in,实际上改变了现有列表的顺序)并且不返回新的列表。

在旧版本的Python …

 map(int,str(123)) 

新版本3k

 list(map(int,str(123))) 
 (number/10**x)%10 

您可以在循环中使用它,其中number是完整数字,x是循环(0,1,2,3,…,n)的每次迭代,其中n是停止点。 x = 0给出那个地方,x = 1给出数十,x = 2给出数百,依此类推。 请记住,这将从右到左数字的值,所以这可能不是一个国际标准书号,但它仍然会隔离每个数字。

将其转换为string并用int()函数映射它。

 map(int, str(1231231231)) 

recursion版本:

 def int_digits(n): return [n] if n<10 else int_digits(n/10)+[n%10] 

使用这个循环的主体来做任何你想要的数字

 for digit in map(int, str(my_number)): 

我已经做了这个程序,这里是实际计算我的程序中的校验位的代码位

  #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)) 

它是一行很长的代码,但它将数字分开,将数字乘以适当的数量,将它们加在一起,并用11行代码将它们分开。 .split()函数只是创build一个列表(被分割为十进制),所以你可以把列表中的第二个项目,并从11中find检查数字。 通过改变这两条线,这也可以变得更有效率:

  remainder = no11[1] no11 = (11 - int(remainder)) 

对此:

  no11 = (11 - int(no11[1])) 

希望这可以帮助 :)

类似于这个答案,但更多的“pythonic”迭代digis的方式是:

 while number: # "pop" the rightmost digit number, digit = divmod(number, 10) 

转换为str绝对是慢的,然后除以10。

map比列表理解慢得多:

 convert to string with map 2.13599181175 convert to string with list comprehension 1.92812991142 modulo, division, recursive 0.948769807816 modulo, division 0.699964046478 

这些时间是由我的笔记本电脑上的以下代码返回的:

 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) 

怎么样的单线数字清单…

 ldigits = lambda n, l=[]: not n and l or l.insert(0,n%10) or ldigits(n/10,l) 

答案: 165

方法:蛮力! 这是Python(2.7版本)的一小部分代码count'em所有。

 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) 

假设你想从整数x中得到第i个有效数字,你可以尝试:

 (abs(x)%(10**i))/(10**(i-1)) 

我希望它有帮助。

经过自己的努力search,我发现了几个解决scheme,每个解决scheme都有优点和缺点。 使用最适合你的任务。

在操作系统GNU / Linux Debian 8上使用CPython 3.5进行testing的所有示例。


使用recursion

 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) 

演示

 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) 

使用函数divmod

 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) 

演示

 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) 

使用构造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,) 

使用函数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,) 

使用模块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)