所以我学习用Python编写代码(以前没有学过另一种语言)并且正在进行第二次练习:http://cscircles.cemc.uwaterloo.ca/15b-python-pushups/
我制作了一个有效的代码但我无法帮助,但觉得必须有一种方法可以用更少的行来实现,这是我目前的解决方案:
def check(S):
a = S.replace(' ', '')
if len(S) != 19:
return False
try:
int(a)
except ValueError:
return False
lister = []
for i in range (0, len(a)):
lister.append(int(a[i]))
if sum(lister)%10 != 0:
return False
if sum(lister) == 0:
return False
return True
第一名:
有没有更好的方法来检查所有字符是否为数字?我知道.isdigit()方法但不确定如何实现它,这有用吗?
对于a.isdigit():
如果错:
返回False
第二个:
是否有更好的方法可以使用'或者#39;来检查条件,例如我的代码的这一部分:
if sum(lister)%10 != 0:
return False
if sum(lister) == 0:
return False
我能以某种方式将两者结合起来吗?
答案 0 :(得分:2)
您可以将行更改为:
for i in range(len(a)):
lister.append(int(a[i]))
return sum(lister) % 10 == 0 or sum(lister) == 0
如果 条件为return True
或True
,如果 <{1}} <,则最后一行将为False
< / p>
您也可以迭代a并使用列表comp:
True
您还可以使用generator expression
进一步优化计算总和lister = [int(i) for i in a ]
return sum(lister) % 10 == 0 or sum(lister) == 0
您的初始检查可以使用all功能和str.isdigit检查所有数字,以便您删除lister_sum = sum(int(i) for i in a )
return lister_sum % 10 == 0 or lister_sum == 0
:
try/except
所以你的最终功能是:
if len(S) != 19 or not all(x.isdigit() for x in a)
使用try / except使用map:
def check(s):
# split into individual strings
spl = s.split()
# make sure format is #### #### #### ####
if len(spl) != 4 or not all(len(x) == 4 for x in spl):
return False
a = s.replace(" ","")
elif len(s) != 19 or not all(x.isdigit() for x in a):
return False
lister_sum = sum(int(i) for i in a)
return lister_sum % 10 == 0
答案 1 :(得分:2)
a
上的检查之前,请不要创建S
。try: int(a)
代码也接受一些应该拒绝的内容。例如,如果字符串以-
开头,则此检查将通过,但是当函数int(a[0])
时,您的函数将稍后抛出异常。在这种情况下它应该返回False
,而不是抛出异常。if sum(lister) == 0: return False
似乎有误,因为没有什么可以说0000 0000 0000 0000
应该被拒绝。我认为这不是一个真正的信用卡号码,但这与所述问题无关; - )在评论中回答您的问题,是的,您可以比创建列表更简洁。以下称为“生成器理解”,您应该在Python参考中查找:
sum(int(d) for d in a)
最后,每当你有一个以:
结尾的函数时if something:
return False
return True
考虑是否写得更好:
return not something
答案不是总是它会更好,但它肯定更简洁。
把所有东西放在一起:
def check(s):
if len(s) != 19:
return False
# there's more than one way to check this, a regex is fine, but another way is
expected_spaces = (4, 9, 14)
for idx, ch in enumerate(s):
if (ch == ' ') != (idx in expected_spaces):
return False
try:
checksum = sum(int(d) for d in s if d != ' ')
return checksum % 10 == 0
# or you might prefer a one-liner:
# return sum(int(d) for d in s if d != ' ') % 10 == 0
except ValueError:
return False
请注意,调用int()
会检查字符是否为数字(如果没有则会抛出异常),但是它接受非英文数字,例如Unicode U+0660
,“阿拉伯语 - 印度数字零”。问题陈述没有说明是否允许这样做,但如果没有,那么你需要额外检查这段代码。另一方面,Matt的正则表达式专门测试ASCII数字。
答案 2 :(得分:1)
您无需将所需的字符串格式硬编码为数组索引或正则表达式。您可以使用给定的格式字符串并使用它来解析数字。然后,您可以分别根据相应的格式检查每个字符,并使用数字添加到校验和。
以下是一个例子:
def check(s):
# the format string:
# "#" digit character, " ": space character
fmt = "#### #### #### ####"
# check length of input string
if len(s) != len(fmt):
return False
# compute checksum and validate format
checksum = 0
# iterate "zipped" format and input string
for f,i in zip(fmt, s):
if f == "#":
# expecting i to be digit
try:
checksum += int(i)
except ValueError:
# i is not a digit
return False
elif i != " ":
# expected i to be space (but it's not)
return False
# validate checksum
return not checksum%10
供参考:
答案 3 :(得分:0)
这将完成练习:
import re
re_credit = re.compile(r'^([0-9]{4}) ([0-9]{4}) ([0-9]{4}) ([0-9]{4})$')
def check(s):
if not re_credit.match(s):
return False
checksum = 0
for c in s.replace(' ', ''):
checksum += int(c)
if (checksum % 10) != 0:
return False
return True