Python效率查询

2024-04-29 09:45:16 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我正在学习用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

第二点: 有没有更好的方法可以使用“or”立即检查条件,例如我的代码的以下部分:

if sum(lister)%10 != 0:
     return False
  if sum(lister) == 0:
    return False

我能把两者结合起来吗?你知道吗


Tags: 方法代码语言falsehttplenreturnif
3条回答

不需要将所需的字符串格式硬编码到数组索引或正则表达式中。您只需获取给定的格式字符串并使用它来解析数字。然后,您可以根据各自的格式分别检查每个字符,并使用这些数字添加到校验和中。你知道吗

举个例子:

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

供参考:

  • 您的代码接受一些应该拒绝的输入。例如,它接受后跟三个空格的16位数字,而它应该验证空格的位置。你知道吗
  • 它是常规的(虽然不是必需的),并且通常有助于可读性一点,如果你不介绍东西,直到他们需要。例如,在直接完成对S的检查之前,不要创建a。你知道吗
  • 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数字。你知道吗

您可以将行更改为:

for i in range(len(a)):
     lister.append(int(a[i]))
return sum(lister) % 10 == 0 or sum(lister) == 0

最后一行将return True如果条件是TrueFalse如果两者都不是True

您也可以只迭代一个并使用列表comp:

lister = [int(i) for i in a ]
return sum(lister) % 10 == 0 or sum(lister) == 0

您还可以进一步优化,只需使用generator expression计算一次和:

lister_sum = sum(int(i) for i in a )
return lister_sum % 10 == 0 or lister_sum == 0

您的初始检查可以使用all函数和str.isdigit检查所有数字,这样您就可以删除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/除了使用map

def check(s):
    if len(s) != 19:
        return False
    spl = s.split()
    if len(spl) != 4 or not all(len(x) == 4 for x in spl):
        return False
    a = s.replace(" ","")
    try:
         a = list(map(int,a))
    except ValueError:
        return False
    return sum(a) % 10 == 0

相关问题 更多 >