Python,更智能的字符串转整数方法

2 投票
4 回答
5759 浏览
提问于 2025-04-15 20:44

我写了这段代码,用来把格式像“0(532) 222 22 22”的字符串转换成整数,比如05322222222。

class Phone():
    def __init__(self,input):
        self.phone = input
    def __str__(self):
        return self.phone
    #convert to integer.
    def to_int(self):
        return int((self.phone).replace(" ","").replace("(","").replace(")",""))

test = Phone("0(532) 222 22 22")
print test.to_int()

我觉得用三个替换方法来解决这个问题有点笨拙。我想知道有没有更好的办法?

4 个回答

1

那就直接用正则表达式怎么样?

举个例子:

>>> import re
>>> num = '0(532) 222 22 22'
>>> re.sub('[\D]', '', num) # Match all non-digits ([\D]), replace them with empty string, where found in the `num` variable.
'05322222222'

ChristopheD 提出的建议是可以用的,但效率没有那么高。

下面是一个测试程序,用来展示如何使用 dis 模块(想了解更多详细信息,可以查看 Doug Hellman 的 PyMOTW 里关于这个模块的内容,链接在这里)。

TEST_PHONE_NUM = '0(532) 222 22 22'

def replace_method():
    print (TEST_PHONE_NUM).replace(" ","").replace("(","").replace(")","")

def list_comp_is_digit_method():
    print ''.join([x for x in TEST_PHONE_NUM if x.isdigit()])

def translate_method():
    print (TEST_PHONE_NUM).translate(None,' ()')

import re
def regex_method():
    print re.sub('[\D]', '', TEST_PHONE_NUM)

if __name__ == '__main__':
    from dis import dis

    print 'replace_method:'
    dis(replace_method)
    print
    print

    print 'list_comp_is_digit_method:'
    dis(list_comp_is_digit_method)

    print
    print

    print 'translate_method:'
    dis(translate_method)

    print
    print
    print "regex_method:"
    dis(phone_digit_strip_regex)
    print

输出结果:

replace_method:
  5       0 LOAD_GLOBAL              0 (TEST_PHONE_NUM)
          3 LOAD_ATTR                1 (replace)
          6 LOAD_CONST               1 (' ')
          9 LOAD_CONST               2 ('')
         12 CALL_FUNCTION            2
         15 LOAD_ATTR                1 (replace)
         18 LOAD_CONST               3 ('(')
         21 LOAD_CONST               2 ('')
         24 CALL_FUNCTION            2
         27 LOAD_ATTR                1 (replace)
         30 LOAD_CONST               4 (')')
         33 LOAD_CONST               2 ('')
         36 CALL_FUNCTION            2
         39 PRINT_ITEM          
         40 PRINT_NEWLINE       
         41 LOAD_CONST               0 (None)
         44 RETURN_VALUE   

phone_digit_strip_list_comp:
  3           0 LOAD_CONST               1 ('0(532) 222 22 22')
              3 STORE_FAST               0 (phone)

  4           6 LOAD_CONST               2 ('')
              9 LOAD_ATTR                0 (join)
             12 BUILD_LIST               0
             15 DUP_TOP             
             16 STORE_FAST               1 (_[1])
             19 LOAD_GLOBAL              1 (test_phone_num)
             22 GET_ITER            
             23 FOR_ITER                30 (to 56)
             26 STORE_FAST               2 (x)
             29 LOAD_FAST                2 (x)
             32 LOAD_ATTR                2 (isdigit)
             35 CALL_FUNCTION            0
             38 JUMP_IF_FALSE           11 (to 52)
             41 POP_TOP             
             42 LOAD_FAST                1 (_[1])
             45 LOAD_FAST                2 (x)
             48 LIST_APPEND         
             49 JUMP_ABSOLUTE           23
             52 POP_TOP             
             53 JUMP_ABSOLUTE           23
             56 DELETE_FAST              1 (_[1])
             59 CALL_FUNCTION            1
             62 PRINT_ITEM          
             63 PRINT_NEWLINE       
             64 LOAD_CONST               0 (None)
             67 RETURN_VALUE   

translate_method:
  11           0 LOAD_GLOBAL              0 (TEST_PHONE_NUM)
               3 LOAD_ATTR                1 (translate)
               6 LOAD_CONST               0 (None)
               9 LOAD_CONST               1 (' ()')
              12 CALL_FUNCTION            2
              15 PRINT_ITEM          
              16 PRINT_NEWLINE       
              17 LOAD_CONST               0 (None)
              20 RETURN_VALUE      

phone_digit_strip_regex:
  8       0 LOAD_CONST               1 ('0(532) 222 22 22')
          3 STORE_FAST               0 (phone)

  9       6 LOAD_GLOBAL              0 (re)
          9 LOAD_ATTR                1 (sub)
         12 LOAD_CONST               2 ('[\\D]')
         15 LOAD_CONST               3 ('')
         18 LOAD_GLOBAL              2 (test_phone_num)
         21 CALL_FUNCTION            3
         24 PRINT_ITEM          
         25 PRINT_NEWLINE       
         26 LOAD_CONST               0 (None)
         29 RETURN_VALUE        

translate 方法是最有效率的,不过需要 Python 2.6 以上的版本。正则表达式的效率稍微低一点,但兼容性更好(我觉得这对你来说很重要)。而原来的 replace 方法每替换一次会多加 6 条指令,而其他方法则保持不变。

顺便提一下,存储电话号码时最好用字符串格式,这样可以处理前面的零,并在需要的时候使用电话格式化工具。相信我,这个问题我之前遇到过。

6

在Python 2.6或2.7中,
(self.phone).translate(None,' ()')
这段代码会把电话号码中的空格、左括号(和右括号)都去掉。想了解更多,可以查看Python 2.6的文档

而在Python 3.x中,str.translate()方法需要一个映射(而不是像上面那样的两个字符串)。所以对应的代码大概是这样的,使用str.maketrans()来生成这个映射。
'(self.phone).translate(str.maketrans('','', '()-/ '))
想了解更多,可以查看Python 3.1的文档

9
p = "0(532) 222 22 22"
print ''.join([x for x in p if x.isdigit()])

注意,如果你想把它转换成整数(就像你在标题中提到的那样),你会“丢失”前面的零。如果你想这么做,只需把上面的内容放在一个 int() 的调用里。不过,我觉得电话号码作为字符串更合适。

撰写回答