首页 > 解决方案 > 避免重复 if 语句

问题描述

我为此任务准备了函数并排序了数据:(实际上是 AoC 第 4 天,但要快速解释清楚)我已经将数据排序到这个“结构”

byr:1991
eyr:2022
hcl:#341e13
iyr:2016
pid:729933757
hgt:167cm
ecl:gry

hcl:231d64
cid:124
ecl:gmt
eyr:2039
hgt:189in
pid:#9c3ea1

ecl:#1f58f9
pid:#758e59
iyr:2022
hcl:z
byr:2016
hgt:68
eyr:1933

[等等 +250 个包(包我的意思是一组 byr,ecl,eyr... 由新行分隔)。]

并准备了这段代码:

def check_fields(list):
    comparison_list = ['byr', 'iyr', 'eyr',
                       'hgt', 'hcl', 'ecl',
                       'pid']
    statement = True
    for i in comparison_list:
        statement = statement and (i in list)
    return statement


def check_byr_iyr_eyr(line):
    prefix,value = line.split(':')
    cases = {'byr':{'min':1920, 'max':2002},
             'iyr':{'min':2010, 'max':2020},
             'eyr':{'min':2020, 'max':2030} }
    return cases[prefix]['min'] <= int(value) <= cases[prefix]['max']


def check_hgt(line):
    unit = line[len(line)-2] + line[len(line)-1]
    value = line[line.index(':')+1: -2]
    cases = {'cm':{'min':150, 'max':193},
             'in':{'min':59, 'max':76}}
    return cases[unit]['min'] <= int(value) <= cases[unit]['max']


def check_hcl(line):
    statement = True
    if line[line.index(':')+1] != '#' or len(line[line.index(':')+2:]) != 6:
        return False
    else:
        string = line[line.index('#')+1:]
        for i in string:
            statement = statement and (97 <= ord(i) <= 102 or 48 <= ord(i) <= 57)
        return statement


def check_ecl(line):
    comparison_list = ['amb', 'blu', 'brn',
                       'gry', 'grn', 'hzl',
                       'oth' ]
    if line[line.index(':') + 1:] in comparison_list:
        return True
    return False


def check_pid(line):
    if len(line[line.index(':')+1:]) != 9:
        return False
    try:
        int(line[line.index(':')+1:])
        return True
    except:
        return False


line_list = []
valid_passports = 0
with open('results.txt', 'r') as f:
    for line in f:
        if line != '\n':
            ''' add line to line_list'''
            pass
        else:
            '''
            check lines from line_list
            using above declared functions
            if every line is ok:
                valid_passports +=1
            '''

我必须检查每个包是否包含除 cid 之外的每个键,然后检查每个键的每个值是否正确。

byr (Birth Year) - four digits; at least 1920 and at most 2002.
iyr (Issue Year) - four digits; at least 2010 and at most 2020.
eyr (Expiration Year) - four digits; at least 2020 and at most 2030.
hgt (Height) - a number followed by either cm or in:
If cm, the number must be at least 150 and at most 193.
If in, the number must be at least 59 and at most 76.
hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f.
ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth.
pid (Passport ID) - a nine-digit number, including leading zeroes.
cid (Country ID) - ignored, missing or not. 

(上述规则由前面声明
的函数确保)问题/问题是如何在检查添加到行列表的每一行时避免重复 if 语句(它指的是带有“伪代码”的多​​行注释部分)?- 我的意思是我可以这样做

if line[0:3] == "byr":
    check_byr(line)
# and so on, many if statement checking the first 3 letters to adjust proper function to use

但这似乎不是正确而优雅的解决方案,也许你可以给我提示如何处理这个问题,或者给出另一个想法以我没有使用的不同方式解决这个问题。请帮忙,谢谢。

标签: pythonalgorithmif-statementrepeat

解决方案


你不能有从前缀到目标函数的映射吗?

就像是

line = # ...
prefix = # ... either "hgt" or "pid" or other

def check_hgt(line):
    pass
def check_pid(line):
    pass
# ... other checker functions

checker_functions_pool = {"hgt": check_hgt, "pid": check_pid}

checker_function = checker_functions_pool[prefix]
checker_function(line)

推荐阅读