Python效率查询

时间:2014-08-26 16:35:23

标签: 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

第二个: 是否有更好的方法可以使用'或者#39;来检查条件,例如我的代码的这一部分:

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

我能以某种方式将两者结合起来吗?

4 个答案:

答案 0 :(得分:2)

您可以将行更改为:

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

如果 条件为return TrueTrue,如果 <{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)

  • 您的代码接受一些应该拒绝的输入。例如,它接受16个数字后跟三个空格,而它应该验证空格的位置。
  • 这是传统的(虽然没有必要),如果你在需要之前不介绍东西,通常会有一点帮助。例如,在您完成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