Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python效率查询_Python - Fatal编程技术网

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

因此,我正在学习用Python编写代码(以前从未学习过其他语言),并在以下位置进行第二个练习:

我编写了一段代码,但我情不自禁地觉得一定有一种方法可以用更少的行来完成,下面是我当前的解决方案:

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()
检查字符是否为数字(如果不是,则引发异常),但它接受非英语数字,如Unicode
U+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