56

我正在编写一个计算 ISBN 号校验位的程序。我必须将用户的输入(ISBN 的九位数字)读入一个整数变量,然后将最后一位数字乘以 2,倒数第二位乘以 3,依此类推。我怎样才能将整数“拆分”成它的组成数字来做到这一点?由于这是一项基本的家庭作业,我不应该使用列表。

4

15 回答 15

88

只需从中创建一个字符串。

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

或者更好的是,不要将用户的输入转换为整数(用户键入字符串)

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

有关更多信息,请阅读教程

于 2009-06-10T11:11:07.597 回答
77
while number:
    digit = number % 10

    # do whatever with digit

    # remove last digit from number (as integer)
    number //= 10

在循环的每次迭代中,它都会从 number 中删除最后一位数字,并将其分配给digit. 它是相反的,从最后一个数字开始,以第一个数字结束

于 2009-06-10T11:30:36.293 回答
23
list_of_ints = [int(i) for i in str(ISBN)]

会给你一个有序的整数列表。当然,考虑到鸭子类型,您不妨使用 str(ISBN)。

编辑:正如评论中提到的,这个列表没有按升序或降序排序,但它确实有一个定义的顺序(python 中的集合、字典等理论上没有,尽管实际上顺序倾向于相当可靠)。如果要排序:

list_of_ints.sort()

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

于 2009-06-10T11:12:53.707 回答
14

在旧版本的 Python...

map(int,str(123))

在新版本 3k

list(map(int,str(123)))
于 2010-09-14T06:07:16.540 回答
4
(number/10**x)%10

您可以在循环中使用它,其中 number 是整数,x 是循环的每次迭代 (0,1,2,3,...,n),n 是停止点。x = 0 给出个位,x = 1 给出十位,x = 2 给出百位,依此类推。请记住,这将从右到左给出数字的值,因此这可能不是 ISBN 的值,但它仍会隔离每个数字。

于 2014-04-09T13:24:56.010 回答
2

将其转换为字符串并使用 int() 函数对其进行映射。

map(int, str(1231231231))
于 2011-10-16T22:19:24.933 回答
2

递归版本:

def int_digits(n):
    return [n] if n<10 else int_digits(n/10)+[n%10]
于 2012-09-15T08:38:56.707 回答
2

转换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)
于 2013-07-03T21:33:35.830 回答
2

经过自己的勤奋搜索,我找到了几个解决方案,每个都有优点和缺点。使用最适合您的任务。

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


使用递归

代码

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)
于 2017-03-11T17:25:31.267 回答
1

使用此循环的主体对数字执行任何操作

for digit in map(int, str(my_number)):
于 2014-01-13T21:51:31.560 回答
1

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

    #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() 函数只是创建一个列表(以小数点拆分),因此您可以获取列表中的第二项并从 11 中获取校验位。这也可以通过改变这两行来提高效率:

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

对此:

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

希望这可以帮助 :)

于 2014-01-16T09:48:27.287 回答
1

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

while number:
    # "pop" the rightmost digit
    number, digit = divmod(number, 10)
于 2015-05-08T22:31:46.133 回答
0

单行数字列表怎么样...

ldigits = lambda n, l=[]: not n and l or l.insert(0,n%10) or ldigits(n/10,l)
于 2010-09-14T05:20:40.703 回答
0

答案: 165

方法:暴力!这里有一点点 Python(2.7 版)代码来计算它们。

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)
于 2015-09-14T14:32:51.410 回答
0

假设您想从整数x中获取第i个最低有效位,您可以尝试:

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

我希望它有所帮助。

于 2015-09-16T19:09:35.330 回答