首页 > 代码库 > 深入一步探索Python计算身份证校验位的代码写法【map -> imap】

深入一步探索Python计算身份证校验位的代码写法【map -> imap】

根据身份证末位的校验位计算方法,写出了python版的。

根据别人写的一个修改得到:

用到map, zip, sum

  1. #!/usr/bin/env python
  2. def check_bit( string ):
  3.         s = map( int, string )
  4.         a = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
  5.         b = sum( map( lambda x: x[0]*x[1], zip(a, s) ) )
  6.         c = b % 11
  7.         d = [‘1‘, ‘0‘, ‘x‘, ‘9‘, ‘8‘, ‘7‘, ‘6‘, ‘5‘, ‘4‘, ‘3‘, ‘2‘]
  8.         return d[c]
  9.        
  10. if __name__ == ‘__main__‘:
  11.     print check_bit( ‘22132119880830001‘ ) # 1
  12.     print check_bit( ‘32010519820927512‘ ) # 7

可是一点都不pythonic,于是修改函数成:

check_bit = lambda string: ['1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'][sum( map( lambda x: x[0]*x[1], zip([7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2], map( int, string )) ) ) % 11]

顺水推舟,原来的代码写成一句话:

print repr(  map( lambda string: ['1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'][sum( map( lambda x: x[0]*x[1], zip([7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2], map( int, string )) ) ) % 11], ('22132119880830001', '32010519820927512') )  )

在引入itertools模块后,又写了下面几种:


imap + izip +sum (imap产生迭代器,map产生列表)

print repr( [ i for i in imap( lambda string: ['1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'][sum( imap( lambda x: x[0]*x[1], izip([7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2], imap( int, string )) ) ) % 11], ('22132119880830001', '32010519820927512') )]  )

print repr(list(  imap( lambda string: ['1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'][sum( imap( lambda x: x[0]*x[1], izip([7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2], imap( int, string )) ) ) % 11], ('22132119880830001', '32010519820927512') )  ))


imap + reduce + chain

print repr( [ i for i in imap( lambda string: ['1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'][ reduce( lambda x,y: x+y, imap( lambda x,y: x*int(y), [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2], chain( string ) ) ) % 11], ('22132119880830001', '32010519820927512') )]  )


starmap +reduce + izip (string需要写成*string)

print repr( [ i for i in starmap( lambda *string: ['1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'][reduce( lambda x,y: x+y, starmap( lambda x,y: x*y, izip([7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2], starmap( int, string )) ) ) % 11], ['22132119880830001', '32010519820927512'] )]  )