Python效率查询
因此,我正在学习用Python编写代码(以前从未学习过其他语言),并在以下位置进行第二个练习: 我编写了一段代码,但我情不自禁地觉得一定有一种方法可以用更少的行来完成,下面是我当前的解决方案:Python效率查询,python,Python,因此,我正在学习用Python编写代码(以前从未学习过其他语言),并在以下位置进行第二个练习: 我编写了一段代码,但我情不自禁地觉得一定有一种方法可以用更少的行来完成,下面是我当前的解决方案: def check(S): a = S.replace(' ', '') if len(S) != 19: return False try: int(a) except ValueError: return False lister = [] fo
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():
如果为假:
返回错误
第二:
是否有更好的方法使用“或”立即检查条件,例如我代码的这一部分:
if sum(lister)%10 != 0:
return False
if sum(lister) == 0:
return False
我可以将这两行组合起来吗?您可以将行更改为:
for i in range(len(a)):
lister.append(int(a[i]))
return sum(lister) % 10 == 0 or sum(lister) == 0
如果条件为True
或者条件为True
或者False
如果两者都不为True
您也可以只迭代一次,然后使用列表comp:
lister = [int(i) for i in a ]
return sum(lister) % 10 == 0 or sum(lister) == 0
您还可以进一步优化,只需使用以下公式计算一次总和:
您的初始检查可以使用该功能检查所有数字,因此您可以删除try/except
:
if len(S) != 19 or not all(x.isdigit() for x in a)
因此,您的最终功能是:
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
使用try/except使用:
这将完成以下练习:
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
- 您的代码接受一些应该拒绝的输入。例如,它接受后跟三个空格的16位数字,而它应该验证空格的位置
- 它是常规的(虽然不是必需的),如果你在需要之前不介绍东西,通常会对可读性有一点帮助。例如,在您直接完成对
S
的检查之前,不要创建a
try:int(a)
代码也接受一些它应该拒绝的东西。例如,如果字符串以-
开头,则该检查将通过,但随后函数在执行int(a[0])
时将抛出异常。在这种情况下,它应该返回False
,而不是抛出异常
if sum(lister)==0:return False
从问题描述来看似乎是错误的,因为没有什么可以说明应该拒绝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()
检查字符是否为数字(如果不是,则引发异常),但它接受非英语数字,如UnicodeU+0660
,“阿拉伯-印度数字零”。问题声明没有说明这是否允许,但如果不允许,则需要对代码进行额外检查。另一方面,Matt的正则表达式专门测试ASCII数字。您不需要将所需的字符串格式硬编码到数组索引或正则表达式中。您只需获取给定的格式字符串并使用它来解析数字。然后,您可以根据各自的格式单独检查每个字符,并使用数字添加到校验和中
下面是一个例子:
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
供参考:
sum(int(d) for d in a)
我相信这个问题属于。正则表达式将有助于检查信用卡号的有效性。如果不是。isdigit():return False
谢谢你的提示Korem,我将把它添加到我的收藏夹中,GWW谢谢-我会研究一下的。有没有什么方法可以比将字符串转换为列表更快地求和?谢谢-这正是我想要的哦,还有,有没有什么方法可以让我更容易地求和?将其转换为列表似乎很冗长。@VimalKarsan,不用担心,您可以进行更多优化,但最重要的是做好基础工作。我加了一个方法来求和once@VimalKarsan,我添加了一些额外的行。我不知道这个问题需要格式化。谢谢你的帮助,我真的很感激。你用一个变量来命名内置函数sum()
。@moooeeep-true,但是只在函数的局部范围内,并且它是变量的正确名称。特别是在建议初学者的上下文中,我不建议这样做。你可以称它为校验和之类的。这是一个普遍的问题,除非你的函数被详细命名为get\u X
或compute\u X
,否则返回值的一个候选逻辑名通常是函数的逻辑名。这些值是某物的总和,某物的最大值,某物的罪恶,某物的列表,等等,不管你是从函数中还是从其他方面得到的。解决方案通常是在命名值时稍微具体一点,如果它的作用域中也有一个函数来计算相同的东西。在这种情况下,它可能是digitsum
。非常感谢,这比我的代码要好得多。非常感谢-我将在将来记住这一点。
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