我正在网上做一些教程...我被困在一个练习中:定义一个函数postalValidate(S)
,该函数首先检查 S 是否表示有效的邮政编码。注意:我应该用字符串、列表、if 语句、循环和其他基本结构(如变量和函数)来解决它。
首先,删除所有空格; 其余部分必须采用L#L#L#
形式,其中L
是字母(小写或大写),#
是数字。
如果S
不是有效的邮政编码,则返回布尔False
。如果S
有效,则以 nice 格式返回同一邮政编码的版本,L#L#L#
其中每个L
都是大写的。
我已经为这些练习创建了一个代码,但评分员说这是错误的,但我也会发布它。
def postalValidate(S):
while " " in S:
S.remove(" ")
for i in range(1,6,2):
S.isdigit(S[i])
for j in range(0,5,2):
S.upper(S[j]
S.isalpha(S[j])
return True
这显然是正则表达式的工作,尽管我不知道您是否应该在练习中使用它们......
我将其作为答案发布,以防万一。否则,请告诉我们...
#/usr/bin/evn python
import re
zipCode = re.compile(r"s*(wds*){3}s*")
if __name__ == "__main__":
samples = [
" 44F 4 F", #Invalid
" L0L0L0 ", #Valid
" L0 L0 L0 ", #Valid
]
for sample in samples:
if zipCode.match(sample):
print "The string %s is a valid zipCode (nice and clean: %s)" % (sample, sample.replace(" ", "").upper())
else:
print "The string %s is NOT a valid zipCode" % sample
编辑:
由于你不能使用正则表达式,我建议你改变思维方式......与其检查字符是否属于有效的邮政编码,我建议您执行相反的操作:检查它们是否不属于有效的邮政编码,一旦检测到放错位置(或错误)的字符,就返回 False:
def postalValidate(S):
S = S.upper().replace(" ", "")
if len(S) == 6:
for i in range(len(S)):
if i % 2 == 0:
#Even index (0, 2, 4, 6...) , has to be 'letter'
if not(S[i].isalpha()):
return False
else:
#Odd index (1, 3, 5, 7...), must be 'number'
if not(S[i].isdigit()):
return False
else:
#You can save some cpu ticks here... at this point, the string has to be of length 6 or you know it's not a zip
return False
return S
return 语句停止当前函数的执行,因此一旦您意识到要检查的字符串有"错误",您就可以返回 False(一旦您知道它无效,就没有必要继续检查,对吧?
import re
def postalValid(S):
spaceless = S.replace(' ','')
if not re.match(r"[a-zA-Z][0-9]+[a-zA-Z][0-9]+[a-zA-Z][0-9]+",spaceless):
return False
return spaceless.upper()
正则表达式(Python RE 模块)在字符串中查找模式。
[a-zA-Z]
将正好匹配 1 个字母
[0-9]+
将匹配一个或多个数字(即 0,9,99,9999)...如果您只想要一个数字,只需删除 [0-9]+
中的加号运算符并使其[0-9]
它将与一位数字完全匹配
所以 [a-zA-Z][0-9]+[a-zA-Z][0-9]+[a-zA-Z][0-9]+
匹配一个字母后跟一个数字(多位数可以),后跟一个字母,后跟另一个数字,后跟另一个字母,以数字结尾
如果您不能使用正则表达式,那么您可以这样做
def postalValid(S):
no_spaces = S.replace(" ","")
if len(no_spaces ) > 6: return false
for i in range(6):
if i%2:
if not no_spaces[i].isdigit():return False
else:
if not no_spaces[i].isalpha():return False
return no_spaces.upper() #True
但这假设每个数字只有一个数字
我碰巧在同一个教程上工作,具有相同的编码约束。经过几个小时的挠头:
def postalValidate(S):
S = S.replace(" ","")
if len(S) != 6 or S.isalpha() or S.isdigit():
return False
if not S[0:5:2].isalpha():
return False
if not S[1:6:2].isdigit():
return False
return S.upper()
import re
regex ="[a-zA-Z]+d+[a-zA-Z]+d+[a-zA-Z]+d+"
def ispostal(v):
v = re.sub('s+', '', v)
if re.match(regex, v):
return v.upper()
else:
return False
我不是在发布确切的代码,而只是发布算法。请阅读内联评论。(注意:以下不是python代码。
def postalValidate(S):
while " " in S:
S.remove(" ") #Are you sure this will work? Strings are immutable.. You need to assign back to `S`
for i in range(1,6,2):
if s[i] is not a digit:
return False
for j in range(0,5,2):
S.upper(S[j]) # you need to assign to S[j] again, plus use ".upper()"
if S[j] is not alpha:
return False
return s.upper() #simple .upper() will do the job.
如果你可以使用 re
,它将像以下一样简单:
if re.search(r'^([a-zA-Z][0-9]){3}$', s.strip()):
return s.strip().upper()
return False
所以大概 S 是一个字符串,所以我会离开它。 首先,您错误地调用了isdigit和isalpha,其次,如果它不是有效的邮政编码,则永远不会返回false。 无论代码中发生什么情况,return True
始终返回 True。 以下是我认为您要做的:
def postal_validate(s):
s = s.replace(' ', '')
for i in range(1,6,2):
if (not s[i].isdigit()):
return False
for i in range(0,5,2):
if (not s[i].isalpha()):
return False
return s.upper()
当然,我可能是错的。
下面是编写和验证练习函数的相对简单的方法。第一个空格字符将从字符串参数中删除,这会在此过程中创建它的本地副本。然后返回布尔值,具体取决于稍长的逻辑表达式中的每个子表达式的计算结果是否为 True。
def postalValidate(s):
s = s.replace(" ", "")
return(len(s) == 6 and
all(s[i].isdigit() for i in range(1, 6, 2)) and
all(s[i].isalpha() for i in range(0, 5, 2)))
if __name__ == '__main__':
for testcase in 'a1b2c3', '980222', 'A456C7':
print('postalValidate({!r}) -> {}'.format(testcase,
postalValidate(testcase)))
输出:
postalValidate('a1b2c3') -> True
postalValidate('980222') -> False
postalValidate('A456C7') -> False
时已晚,但让我尝试回答这个问题,因为我刚刚完成同样的练习。
根据练习,定义一个函数postalValidate(S)
,该函数首先检查S
是否表示有效的邮政编码(加拿大):
首先,删除所有空格;
其余部分必须是
L#L#L#
的形式,其中L
是字母(在
小写或大写)和 # 是数字。
如果S
不是有效的邮政编码,则返回布尔False
。如果S
有效,则以 nice 格式返回同一邮政编码的版本,L#L#L#
其中每个L
都是大写的。
应该使用他们刚刚介绍的以下方法:
str.replace()
、str.isalpha()
、str.isdigit()
和str.upper()
他们的站点不允许导入模块,因此无法使用正则表达式。
这是我的代码:
def postalValidate(S):
S = S.replace(' ', '')
if len(S) == 6:
if S[::2].isalpha() and S[1::2].isdigit(): # slicing with step
return S.upper()
else:
return False
else:
return False
测试运行包括以下参数:"H0H0H0", "postal", " d3 L3 T3", "3d3 L3 T", ", "n21 3g1z", "V4L1D", "K1A 0A3", "H0H0H"
接受的答案不认为 5 位邮政编码有效。我建议改用O'Reilly的这种模式:
zipCode = re.compile(r"^[0-9]{5}(?:-[0-9]{4})?$")
这适用于所有有效的美国.zip代码。
它可以使用正则表达式轻松完成。但是,如果您正在寻找没有正则表达式的答案,答案如下:
def postalValidate(S):
S=S.replace(" ","")
print(S)
acount=0
dcount=0
for i in range(0,len(S)):
if S[i].isalpha():
acount+=1
if i<len(S):
i=i+1
while(i<len(S) and S[i].isdigit()):
i=i+1
dcount+=1
if acount+dcount==len(S) and acount==3 and dcount>=3:
return S.upper()
else:
return False