是否有内置的 Python 函数或模块可以将数字乘以其整数权重相加?
Is there a built-in Python function or module that will sum digits multiplied by their integer weight?
我需要做的是取一个 10 位的 ISBN 号并根据这个规则检查它是否有效:
According to the 2001 edition of the International ISBN Agency's official user manual,[47] the ISBN-10 check digit (which is the last digit of the 10-digit ISBN) must range from 0 to 10 (the symbol 'X' is used for 10), and must be such that the sum of the ten digits, each multiplied by its (integer) weight, descending from 10 to 1, is a multiple of 11.
也就是说,如果数字是0-306-40615-2,我需要计算:
(0 * 10) + (3 * 9) + (0 * 8) + (6 * 7) + (4 * 6) + (0 * 5) + (6 * 4) + (1 * 3) + (5 * 2) + (2 * 1) mod 11
虽然欢迎提供有关如何编写此类函数的建议或提示,但我的主要问题只是 Python 是否已经有这样做的方法,也许在 math
模块中。
这是我的尝试,但是 for 循环不起作用,因为内部循环一直在重新开始。而且它看起来很乱!
checksum = 0
for digit in isbn:
for weight in range(10, 0, -1):
if digit == 'X':
checksum += 10 * weight
break
checksum += int(digit) * weight
break
return checksum % 11```
不,这太具体了,无法成为标准库中的内容。不过写起来相当简单:
def check_isbn(isbn):
isbn_digits = (
10 if ch == 'X' else int(ch)
for ch in isbn
if ch.isdigit() or ch == 'X')
checksum = sum(
(10 - index) * digit
for index, digit
in enumerate(isbn_digits)
) % 11
return checksum % 11 == 0
我喜欢理解的方式;但命令式的方式也应该有效,你只是有一些逻辑错误。特别是,您不想迭代每个数字的所有权重。如果是数字,每个字符只有一个权重,如果不是,则为 none。因此,命令式重写将是:
def check_isbn(isbn):
checksum = 0
weight = 10
for ch in isbn:
if ch == 'X':
digit = 10
elif ch.isdigit():
digit = int(ch)
else:
continue
checksum += digit * weight
weight -= 1
return checksum % 11 == 0
编辑:各种错误
如果号码是0-306-40615-2,需要计算if
(0 * 10) + (3 * 9) + (0 * 8) + (6 * 7) + (4 * 6) + (0 * 5) + (6 * 4) + (1 * 3) + (5 * 2) + (2 * 1)
是11的倍数,那你写一个简单的函数就可以了。
def check_isbn(isbn): #isbn should be type str
isbn = "".join(isbn.split("-"))
sum = (int(isbn[0]) * 10) + (int(isbn[1]) * 9) + (int(isbn[2]) * 8) + (int(isbn[3]) * 7) + (int(isbn[4]) * 6) + (int(isbn[5]) * 5) + (int(isbn[6]) * 4) + (int(isbn[7]) * 3) + (int(isbn[8]) * 2) + (int(isbn[9]) * 1)
return sum % 11 == 0
check_isbn("1416406110")
# False
check_isbn("0-306-40615-2")
# True
您可以使用列表理解和 enunerate()
来获取前 9 位数字的位置和值。对于每个数字,将位置转换为其反向等效 (10-i)
并将其乘以数字。如果从 990 中减去这些乘法的总和,您将得到一个值,该值将使总和成为 11 的倍数。结果可以用作包含数字 0 到 9 和字母 X 的字符串中的索引:
isbn = "0-306-40615-2"
numbers = [int(n) for n in isbn if n.isdigit()]
check = "0123456789X"[ (990-sum(n*(10-i) for i,n in enumerate(numbers[:9])))%11]
isValid = isbn[-1] == check
print(check) # "2"
我需要做的是取一个 10 位的 ISBN 号并根据这个规则检查它是否有效:
According to the 2001 edition of the International ISBN Agency's official user manual,[47] the ISBN-10 check digit (which is the last digit of the 10-digit ISBN) must range from 0 to 10 (the symbol 'X' is used for 10), and must be such that the sum of the ten digits, each multiplied by its (integer) weight, descending from 10 to 1, is a multiple of 11.
也就是说,如果数字是0-306-40615-2,我需要计算:
(0 * 10) + (3 * 9) + (0 * 8) + (6 * 7) + (4 * 6) + (0 * 5) + (6 * 4) + (1 * 3) + (5 * 2) + (2 * 1) mod 11
虽然欢迎提供有关如何编写此类函数的建议或提示,但我的主要问题只是 Python 是否已经有这样做的方法,也许在 math
模块中。
这是我的尝试,但是 for 循环不起作用,因为内部循环一直在重新开始。而且它看起来很乱!
checksum = 0
for digit in isbn:
for weight in range(10, 0, -1):
if digit == 'X':
checksum += 10 * weight
break
checksum += int(digit) * weight
break
return checksum % 11```
不,这太具体了,无法成为标准库中的内容。不过写起来相当简单:
def check_isbn(isbn):
isbn_digits = (
10 if ch == 'X' else int(ch)
for ch in isbn
if ch.isdigit() or ch == 'X')
checksum = sum(
(10 - index) * digit
for index, digit
in enumerate(isbn_digits)
) % 11
return checksum % 11 == 0
我喜欢理解的方式;但命令式的方式也应该有效,你只是有一些逻辑错误。特别是,您不想迭代每个数字的所有权重。如果是数字,每个字符只有一个权重,如果不是,则为 none。因此,命令式重写将是:
def check_isbn(isbn):
checksum = 0
weight = 10
for ch in isbn:
if ch == 'X':
digit = 10
elif ch.isdigit():
digit = int(ch)
else:
continue
checksum += digit * weight
weight -= 1
return checksum % 11 == 0
编辑:各种错误
如果号码是0-306-40615-2,需要计算if
(0 * 10) + (3 * 9) + (0 * 8) + (6 * 7) + (4 * 6) + (0 * 5) + (6 * 4) + (1 * 3) + (5 * 2) + (2 * 1)
是11的倍数,那你写一个简单的函数就可以了。
def check_isbn(isbn): #isbn should be type str
isbn = "".join(isbn.split("-"))
sum = (int(isbn[0]) * 10) + (int(isbn[1]) * 9) + (int(isbn[2]) * 8) + (int(isbn[3]) * 7) + (int(isbn[4]) * 6) + (int(isbn[5]) * 5) + (int(isbn[6]) * 4) + (int(isbn[7]) * 3) + (int(isbn[8]) * 2) + (int(isbn[9]) * 1)
return sum % 11 == 0
check_isbn("1416406110")
# False
check_isbn("0-306-40615-2")
# True
您可以使用列表理解和 enunerate()
来获取前 9 位数字的位置和值。对于每个数字,将位置转换为其反向等效 (10-i)
并将其乘以数字。如果从 990 中减去这些乘法的总和,您将得到一个值,该值将使总和成为 11 的倍数。结果可以用作包含数字 0 到 9 和字母 X 的字符串中的索引:
isbn = "0-306-40615-2"
numbers = [int(n) for n in isbn if n.isdigit()]
check = "0123456789X"[ (990-sum(n*(10-i) for i,n in enumerate(numbers[:9])))%11]
isValid = isbn[-1] == check
print(check) # "2"