2

我在网上做一些教程......我一直在做一个练习:定义一个函数postalValidate(S),它首先检查 S 是否代表一个有效的邮政编码。注意:我应该用字符串、列表、if 语句、循环和其他基本结构(如变量和函数)来解决它。

首先,删除所有空格;余数必须L#L#L#L字母(小写或大写)和#数字的形式。

如果S不是有效的邮政编码,则返回 boolean False。如果有效,则以每个大写S的漂亮格式返回相同邮政编码的版本。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
4

9 回答 9

4

这显然是正则表达式的工作,虽然我不知道你是否应该在练习中使用它们......

我将其发布为答案,以防万一。否则,请告诉我们...

#/usr/bin/evn python

import re
zipCode = re.compile(r"\s*(\w\d\s*){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(一旦您知道它无效,就没有必要继续检查,对吧?)

于 2012-08-06T16:59:04.490 回答
2
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]与一位数字完全匹配

so [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

但假设每个数字只有一个数字

于 2012-08-06T17:00:24.847 回答
2

我碰巧正在研究同一个教程,具有相同的编码约束。经过几个小时的挠头:

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()  
于 2012-10-22T06:28:11.717 回答
1

所以大概 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()

当然,我可能是错的。

于 2012-08-06T16:59:56.997 回答
1
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
于 2012-08-06T17:00:21.003 回答
1

我没有发布确切的代码,而只是发布算法。请阅读内联评论。(注意:以下不是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
于 2012-08-06T17:03:58.773 回答
1

这是编写和验证练习函数的一种相对简单的方法。从字符串参数中删除第一个空格字符,这会在进程中生成它的本地副本。然后根据有点长的逻辑表达式中的每个子表达式的计算结果是否为 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
于 2012-08-06T17:42:19.863 回答
0

我知道为时已晚,但让我试着回答这个问题,因为我刚刚完成了同样的练习。

根据练习,定义一个函数postalValidate(S),它首先检查是否S代表有效的邮政编码(加拿大):

  • 首先,删除所有空格;

  • 余数必须L#L#L#L字母(
    小写或大写)和# 是数字的形式。

如果S不是有效的邮政编码,则返回 boolean False。如果有效,则以每个大写S的漂亮格式返回相同邮政编码的版本。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'</p>

于 2017-10-02T18:10:00.877 回答
0

接受的答案不认为 5 位邮政编码有效。我建议改用O'Reilly 的这种模式

zipCode = re.compile(r"^[0-9]{5}(?:-[0-9]{4})?$")

这适用于所有有效的美国邮政编码。

于 2021-09-16T22:11:53.383 回答