19

我有一个电话号码(字符串),例如“+123-456-7890”,我想将其转换为如下所示的列表:[+, 1, 2, 3, -, ...., 0]。

为什么?所以我可以遍历列表并删除所有符号,所以我只剩下一个数字列表,然后我可以将其转换回字符串。

解决这个问题的最佳方法是什么?我遇到的所有解决方案都不适用,因为我在数字之间没有任何特殊字符(所以我不能在那里拆分字符串。)

有任何想法吗?对此,我真的非常感激!

编辑 - 这是我尝试过的:

x = row.translate(None, string.digits)
list = x.split()

还:

filter(lambda x: x isdigit())
4

9 回答 9

60

制作一个列表(your_string)

>>> s = "mep"
>>> list(s)
['m', 'e', 'p']
于 2013-03-20T14:50:36.290 回答
9

你的意思是你想要这样的东西:

''.join(n for n in phone_str if n.isdigit())

这利用了字符串是可迭代的事实。当您迭代它们时,它们一次产生 1 个字符。


关于你的努力,

这实际上从字符串中删除了所有数字,只留下非数字。

x = row.translate(None, string.digits)

这一个在空格运行时拆分字符串,而不是在每个字符之后:

list = x.split()
于 2013-03-20T14:50:53.490 回答
6
''.join(filter(str.isdigit, "+123-456-7890"))
于 2013-03-20T14:53:00.613 回答
4

您可以使用 re 模块:

import re
re.sub(r'\D', '', '+123-456-7890')

这将用''替换所有非数字。

于 2013-03-20T14:52:08.480 回答
3

我知道这个问题已经得到解答,但只是timeit指出关于解决方案效率的内容。使用这些参数:

size = 30
s = [str(random.randint(0, 9)) for i in range(size)] + (size/3) * ['-']
random.shuffle(s)
s = ''.join(['+'] + s)
timec = 1000

即“电话号码”有 30 位数字,1 加 sing 和 10 '-'。我已经测试了这些方法:

def justdigits(s):
    justdigitsres = ""
    for char in s:
        if char.isdigit():
            justdigitsres += str(char)
    return justdigitsres

re_compiled = re.compile(r'\D')

print('Filter: %ss' % timeit.Timer(lambda : ''.join(filter(str.isdigit, s))).timeit(timec))
print('GE: %ss' % timeit.Timer(lambda : ''.join(n for n in s if n.isdigit())).timeit(timec))
print('LC: %ss' % timeit.Timer(lambda : ''.join([n for n in s if n.isdigit()])).timeit(timec))
print('For loop: %ss' % timeit.Timer(lambda : justdigits(s)).timeit(timec))
print('RE: %ss' % timeit.Timer(lambda : re.sub(r'\D', '', s)).timeit(timec))
print('REC: %ss' % timeit.Timer(lambda : re_compiled.sub('', s)).timeit(timec))
print('Translate: %ss' % timeit.Timer(lambda : s.translate(None, '+-')).timeit(timec))

并得出了以下结果:

Filter: 0.0145790576935s
GE: 0.0185861587524s
LC: 0.0151798725128s
For loop: 0.0242128372192s
RE: 0.0120108127594s
REC: 0.00868797302246s
Translate: 0.00118899345398s

显然 GE 和 LC 仍然比正则表达式或编译的正则表达式慢。显然我的 CPython 2.6.6 并没有优化字符串添加。translate似乎是最快的(这是预期的,因为问题被表述为“忽略这两个符号”,而不是“获取这些数字”,我相信这是相当低级的)。

对于size = 100

Filter: 0.0357120037079s
GE: 0.0465779304504s
LC: 0.0428011417389s
For loop: 0.0733139514923s
RE: 0.0213229656219s
REC: 0.0103371143341s
Translate: 0.000978946685791s

对于size = 1000

Filter: 0.212141036987s
GE: 0.198996067047s
LC: 0.196880102158s
For loop: 0.365696907043s
RE: 0.0880808830261s
REC: 0.086804151535s
Translate: 0.00587010383606s
于 2013-03-20T15:27:53.240 回答
2

您可以迭代第一个字符串并通过将找到的每个数字字符添加到该新字符串来创建第二个字符串,而不是转换为列表。

于 2013-03-20T14:53:17.650 回答
2

python字符串一个字符列表。您现在可以对其进行迭代!

justdigits = ""
for char in string:
    if char.isdigit():
        justdigits += str(char)
于 2013-03-20T14:50:51.460 回答
2

你试过list(x)吗?

 y = '+123-456-7890'
 c =list(y)
 c

['+', '1', '2', '3', '-', '4', '5', '6', '-', '7', '8', '9', ' 0']

于 2015-08-06T19:48:03.593 回答
0

可以使用str.translate,你只需要给它正确的参数:

>>> dels=''.join(chr(x) for x in range(256) if not chr(x).isdigit())
>>> '+1-617-555-1212'.translate(None, dels)
'16175551212'

注意:这不适用于 Python2 中的 unicode 字符串,或者根本不适用于 Python3。对于这些环境,您可以创建一个自定义类以传递给unicode.translate

>>> class C:
...    def __getitem__(self, i):
...       if unichr(i).isdigit():
...          return i
... 
>>> u'+1-617.555/1212'.translate(C())
u'16175551212'

这也适用于非 ASCII 数字:

>>> print u'+\u00b9-\uff1617.555/1212'.translate(C()).encode('utf-8')
¹6175551212
于 2013-03-20T15:15:54.493 回答