python - 避免重复 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
但这似乎不是正确而优雅的解决方案,也许你可以给我提示如何处理这个问题,或者给出另一个想法以我没有使用的不同方式解决这个问题。请帮忙,谢谢。
解决方案
你不能有从前缀到目标函数的映射吗?
就像是
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)
推荐阅读
- kdb - 访问 kdb+/Q 中的子文件夹
- android - 应用程序版本已在 Play 商店更新,但商店信息未更新
- git - 将 Git 提交合并到具有不同目录的另一个存储库中
- html - 如何将映射图像上传为 LinkedIn 帖子?
- devops - Digital Ocean 中的外部体积监测
- java - 503 服务不可用 - 我的 ingress.yaml 文件有问题吗?
- vb.net - 将图像拉伸到十六进制图片框
- react-native - React Native - 从水平选择器中获取价值
- java - 如何在 PDFBox 中将字符串保存为 PDF?
- sql - 如何查找超过 5 年期间超过设定金额的记录