1

我正在尝试从 12 位 ISBN 返回 ISBN-13 校验位,但遇到了一个奇怪的错误。

将以下内容作为我的 12 位 ISBN - 978311020318

每个数字交替乘以 1 或 3。

9*1 + 7*3 + 8*1 + 3*3 + 1*1 + 1*3 + 0*1 + 2*3 + 0*1 + 3*3 + 1*1 + 8*3 = 91

91 % 10 = 1

10 - 1 = 9,这是我们的 ISBN-13 校验位。

这是我目前所拥有的......

def isbn_check_digit(isbn):
    s = 0
    for i, d in enumerate(isbn):
        if i % 2 == 0:
            s += int(d*1)
        else:
            s += int(d*3)
            print(s)
    return (10 - (s % 10))

print(isbn_check_digit("978311020318"))

输出以下...

786
1127
1239
1461
1794
2683
7

我把它拆开看看发生了什么

    if i % 2 == 0:
        s += int(d*1)
        print(s)
    else:
        s += 0

9
17
18
18
18
19
1

1 的倍数工作正常,但为什么它在 3 的倍数时表现异常?

4

2 回答 2

2

因为,在int(d * 3)计算表达式时,d它不是一个数字——它是一个由一个字符组成的字符串,它是一个数字。结果,将它“乘”以 3 将重复该数字 3 次:例如,3将变成333,而不是9

您想在将字符串转换为整数乘以 3 :

int(d) * 3
于 2014-06-22T05:22:56.957 回答
0

@dustwuff 为您提供了原因,但另一个解决方法是使用map然后将您的字符串转换为列表:

from itertools import izip_longest

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

def isbn_check_digit(isbn):
    number = list(map(int, isbn))
    check_sum = 0
    for i, d in grouper(2, number):
        check_sum += i*1 + d*3
    return 10 - check_sum % 10

map将函数应用于迭代的每个成员。在这种情况下,应用int会将您的字符串转换为数字列表。

于 2014-06-22T05:31:54.987 回答