创建检查代码是否有效的函数时出现的小问题

2024-05-18 06:11:31 发布

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

我试图解决一个rev问题,它要求检查代码是否有效。如果代码由code_letters列表中的1个字母和一定范围内的数字组成,则该代码有效

code_letters = ["S", "B", "N", "T", "P"]
min_for_each_letter = [1, 3, 4, 0, 3] #inclusive
max_for_each_letter = [7, 9, 6, 7, 5] #inclusive

参数:

  • code_letters是对代码字符串的第一个字母有效的代码字母列表
  • min_for_each_letter是一个列表,其中包含该字母后面每个数字的最小可能数字(包括)
  • max_for_each_letter是一个列表,其中包含该字母后面每个数字的最大可能数字(包括)

例如,如果代码包含“S”,则其数字只能介于1和7之间(含1和7),或者如果代码包含“N”,则其数字只能介于4和6之间(含4和6)。
必须只有1个字母和至少1个数字,如果有多个数字,则所有数字都必须在字母范围内才能有效,否则无效

以下是我迄今为止编写的代码:

def is_a_valid_code(code):
    code_letters = ["S", "B", "N", "T", "P"]
    min_for_each_letter = [1, 3, 4, 0, 3] #inclusive
    max_for_each_letter = [7, 9, 6, 7, 5] #inclusive
      
    if code[0] not in code_letters:
        return False
    else:
        x = code_letters.index(code[0])
    
    for ele in code[1:]:
        if ele != " ":
            if ele.isdigit() == False or int(ele) < min_for_each_letter[x] or int(ele) > max_for_each_letter[x]:
                return False
                    
    if not False:
        return True

它适用于测试用例,例如:

is_a_valid_code('B747346')
is_a_valid_codeN('N  444  454')
is_a_valid_codeT('T 400 4854')
is_a_valid_codeS('S  444S454')

但在以下情况下失败:

is_a_valid_code('P  ') # Should return False, not True

有没有办法解释这种情况?我认为有一个简单的修复,但是,ISalpHa()不考虑空白空间


Tags: 代码false列表foris字母code数字
3条回答

在提供的最后一个示例中,'P '(失败),嵌套在for循环中的if语句将检查除P之外的所有字符code[1:]在这种情况下将是" "(两个空格),因此if条件的计算结果为False,因此没有根据代码标准检查任何内容

(另外,在函数的最后一行,not False始终计算为True,因此if语句本身是多余的;相反,只return True会更好。)

我认为最好的方法是创建一个列表,其中包含第一个字符(code[1:])后面每个字符的有效性,然后返回列表中所有元素是否都是True并且列表不是空的(以便像'P '这样的情况不会通过)


def is_valid(code):
    code_letters = ["S", "B", "N", "T", "P"]
    letter_minimum = [1, 3, 4, 0, 3]
    letter_maximum = [7, 9, 6, 7, 5]
    if code[0] not in code_letters:
        return False
    index = code_letters.index(code[0])
    num_range = (letter_minimum[index], letter_maximum[index])
    validity = []
    for i in code[1:]:
        if i == " ":
            continue
        try:
            i = int(i)
            if not (num_range[0] <= i <= num_range[1]):
                validity.append(False)
        except ValueError:
            validity.append(False)
        validity.append(True)
    return bool(all(validity) and validity)

根据提供的示例代码,进行了一些测试运行:

>>> is_valid('B747346')
True
>>> is_valid('N  444  454')
True
>>> is_valid('T 400 4854')    # Fails because 8 is out of the range [0, 7].
False
>>> is_valid('S  444S454')    # Fails because 'S' is not a number
False
>>> is_valid('P  ')    # Fails because no numbers exist
False

代码:

def is_a_valid_code(code):
    code_letters = ["S", "B", "N", "T", "P"]
    min_for_each_letter = [1, 3, 4, 0, 3] #inclusive
    max_for_each_letter = [7, 9, 6, 7, 5] #inclusive
      
    if code[0] not in code_letters:
        return False
    else:
        x = code_letters.index(code[0])
    
    is_non_whitespace_found = False
    for ele in code[1:]:
        if ele != " ":
            is_non_whitespace_found = True
            if ele.isdigit() == False or int(ele) < min_for_each_letter[x] or int(ele) > max_for_each_letter[x]:
                return False
    if not is_non_whitespace_found:
        return False
    else:           
        return True

print(is_a_valid_code('B747346'))
print(is_a_valid_code('N  444  454'))
print(is_a_valid_code('T 400 4854'))
print(is_a_valid_code('S  444S454'))
print(is_a_valid_code('P  '))

结果:

True
True
False
False
False

作为解决这个问题的另一种方法,您可以构造一个与您的需求相匹配的正则表达式,并针对每个输入代码进行测试

对于每个代码字母,我们制作一个正则表达式,看起来像

^S(?:\s*[1-7])+\s*$

它要求代码是一个S,后跟至少一个1到7范围内的数字,还允许一些空格。然后,我们可以将所有这些代码部分放入一个完整的正则表达式中,根据输入值进行测试

例如:

import re

code_letters = ["S", "B", "N", "T", "P"]
min_for_each_letter = [1, 3, 4, 0, 3] #inclusive
max_for_each_letter = [7, 9, 6, 7, 5] #inclusive

regex = re.compile('(?:' + '|'.join(f'{l}(?:\s*[{n}-{x}])+\s*' for l, n, x in zip(code_letters, min_for_each_letter, max_for_each_letter)) + ')$')

def is_a_valid_code(code):
    return regex.match(code) is not None

print(is_a_valid_code('B747346'))
print(is_a_valid_code('N  444  454'))
print(is_a_valid_code('T 400 4854 '))
print(is_a_valid_code('S  444S454'))
print(is_a_valid_code('T 400 4354 '))
print(is_a_valid_code('S  7654 321 '))
print(is_a_valid_code('P    '))

输出:

True
True
False
False
True
True
False

相关问题 更多 >