美文网首页算法
Python算法之旅字符串游戏之无效的身份证

Python算法之旅字符串游戏之无效的身份证

作者: 巧若拙 | 来源:发表于2019-12-28 23:19 被阅读0次

    出场人物介绍

    小美:小学4年级学生,参加了学校的编程兴趣小组,已经了解了Python语言的基本语法,能够看懂一些简单的程序。她做事风风火火,对所有的事情都很好奇,喜欢打破砂锅问到底,是一个叫人又爱又恨的小丫头。

    阿福:一个酷爱编程的8年级男生。大家都说他长得像国宝大熊猫,动作缓慢,憨态可掬。他做事情确实够慢的,连说话也慢条斯理,可是他一点也不担心,他常常说:“慢就是快,只要坚持下去,蜗牛也能爬上金字塔。”

    古老师:虽然年近不惑,但依然对生活充满热情。“爱生活爱运动”是他的人生信条,和孩子们一起编程是他最大的乐趣。他神出鬼没,总是在孩子们最需要帮助的时候出现。当然,你也不能动不动就找古老师,因为他很忙,非常非常忙。所以,遇到问题还是自己先思考吧。


    “Python算法之旅”微信群等着你

    扫码加入“Python算法之旅”微信群,和斌哥面对面交流,更多资料和更有趣的话题等你一起来分享。


     正文

    字符串游戏之无效的身份证


    小美:阿福,上次古老师留下的检验身份证号问题,你找到答案了吗?

    阿福:找到了。身份证最后一位是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

    计算方法:将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2。

    将这17位数字和系数相乘的结果相加;用加出来的和除以11,看余数是多少,余数只可能有0、1、2、3、4、5、6、7、8、9、10这11个数字,其分别对应的身份证最后一位号码为1、0、X、9、8、7、6、5、4、3、2。

    例如,如果余数是0,身份证的第18位数字就是1;如果余数是2,身份证的最后一位号码就是罗马数字X。

    小美:原来是这样。那你上次在示例2中给出的身份证号“330281201010310641”,是先将前17位数字和系数相乘的结果相加,即3*7+3*9+0*10+2*5+8*8+1*4+2*2+0*1+1*6+0*3+1*7+0*9+3*10+1*5+0*8+6*4+4*2 = 210,再将210对11求余数,结果为1。所以,身份证号最后一位数字应该是0。

    阿福:没错。既然你已经知道了检验的原理,那你能不能设计一个函数,根据输入的18位身份证号码,判断该身份证是否为有效身份证呢?

    小美:这有什么难的!看我的。


     问题1

    函数功能:根据输入的18位身份证号码,判断该身份证是否为有效身份证。

    函数名:check_id_num(id_num: str) -> bool

    参数表:id_num -- 存储了18位身份证号码的字符串。

    返回值:如果是有效身份证号返回True,否则返回False。

    示例1:输入id_num='330281200605302813',返回True

    示例2:输入id_num='330281201010310641',返回False


     代码1

    defcheck_id_num(id_num):   

        factor = (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2)#校验码系数

        remainder = '10X98765432'#余数表

        s =0

        for i in range(len(factor)):       

            s += factor[i] *int(id_num[i])

        r = s %11

        return remainder[s%11] == id_num[-1]

    古老师:小美进步很大啊!函数已经写得有模有样了。对了,阿福,你听说过map()函数吗?

    阿福:知道啊,map()函数是一个高阶函数,它接收两个参数,一个是函数,一个是迭代器(可迭代对象),map将传入的函数依次作用到序列的每个元素,并把结果作为新的迭代器返回。

        例如我们有一个函数f(x) = x * x,把该函数作用在一个列表[1, 2, 3, 4, 5, 6]上,就可以用map()实现如下:


     代码2

    deff(x):

        return x * x

    a = list(map(f, [1,2,3,4,5,6]))

        这样就可以得到列表a = [1, 4, 9, 16, 25, 36]。

    古老师:不错,知识点记得挺牢啊!那你知道匿名函数吗?能不能把上面的语句用匿名函数表示?

    阿福:可以,这样只需要一条语句就够了:


     代码3

    a = list(map(lambda x: x * x, [1,2,3,4,5,6]))

     知识小贴士

    python 使用 lambda 来创建匿名函数。所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。lambda的主体是一个表达式,而不是一个代码块,它的语法只包含一个语句,如下:lambda [arg1 [,arg2,.....argn]]:expression


    古老师:没错。那你现在再看看小美写的check_id_num()函数,能不能使用map()函数来表达呢?

    阿福:这个。。。。。。我明白了!可以先使用map()函数生成一个新的序列,再使用内置函数sum()对序列求和,这样可以用一条赋值语句代替原来的for循环。


     代码4

    defcheck_id_num(id_num):

        factor = (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2)#校验码系数

        remainder = '10X98765432'#余数表

        s = sum(map(lambdax, y: x * int(y), factor, id_num))

        return remainder[s%11] == id_num[-1]

    古老师:不错不错!看来你已经领会到map()函数的精髓了。继续努力,迎接更大的挑战。今天就到这吧,下次有事记得叫我。


    温馨提示:

    有事没事最好拉到文末看看,说不定作者今天提供了彩蛋哦!


    需要本文word版的,可以加入“Python算法之旅”知识星球参与讨论和下载文件,“Python算法之旅”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。

    我们专注Python算法,感兴趣就一起来!

     彩蛋

    除了使用map()函数生成一个新的序列,我们还可以用列表生成器来生成新序列,然后使用sum()函数对序列求和。


     代码5

    defcheck_id_num(id_num):   

        factor = (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2)#校验码系数

        remainder = '10X98765432'#余数表

        s = sum([factor[i] *int(id_num[i]) for i in range(len(factor))])   

        r= s %11

        return remainder[s%11] == id_num[-1]

    相关文章

      网友评论

        本文标题:Python算法之旅字符串游戏之无效的身份证

        本文链接:https://www.haomeiwen.com/subject/usueoctx.html