2014-09-12 47 views
-2

我想写一个函数,它过滤掉所有不是字母的字符。 例如,只有字母函数

allLetters( “[email protected]”) - >“HelloWorldcom”

我知道如何做到这一点使用内置的一样,isalpha.join.append功能。

def allLetters2(phrase): 
    l = [] 
    for characters in phrase: 
     if characters.isalpha(): 
     l.append(characters) 
    return ''.join(l) 

但我在寻找一种方式,我不使用这些功能,只使用一个for环和string.ascii_letters。这种结构类似:

def allLetters2(phrase):  
    for characters in phrase: 
     if characters == string.ascii_letters:    
     return characters 
+2

为什么离奇的要求,不使用'isalpha'? '''.join(如果c.isalpha())对c来说是很直截了当的。 – 2014-09-12 20:21:32

+0

@StevenRumbalski我是一名编程新手,想要先学习基础知识。 – Robben 2014-09-12 20:22:34

+3

'如果c.isalpha()'不比'if in string.ascii_letters'更基本。 – 2014-09-12 20:23:43

回答

1

如果您不想使用连接,只需连接:

import string 
def all_letters(s): 
    final = "" 
    for char in s: 
     if char in string.ascii_letters: 
      final += char 
    return final 
In [78]: all_letters("[email protected]") 
Out[78]: 'HelloWorldcom' 

一些时序为不同的方法:

In [90]: %%timeit                
    final = "" 
    for char in s: 
     if char in string.ascii_letters: 
      final += char 
    ....: 
100000 loops, best of 3: 3.97 µs per loop 

In [91]: timeit ''.join(char for char in s if char in string.ascii_letters) 

100000 loops, best of 3: 4.62 µs per loop 

In [92]: timeit ''.join([char for char in s if char in string.ascii_letters]) 

100000 loops, best of 3: 3.8 µs per loop 

In [98]: timeit "".join([x for x in s if x.isalpha()]) 
100000 loops, best of 3: 3.01 µs per loop 

In [102]: timeit s.translate(None, ''.join(set(s)-set(ascii_letters))) 
100000 loops, best of 3: 5.13 µs per loop 
+0

对于小字符串,join(list-comp)技术'“”.join([x for s in x ifis xpha()])''是最好的,但对于更长的字符串're.sub(r'[^ A-Za-z]','',s)'可以明显更快。在我的旧机器上(使用随机生成的字符串),交叉点在len(s)== 50左右。对于len(s)== 1000,正则表达式的时间约为join(list-comp)技术时间的60%。 – 2014-09-13 06:25:30

+0

谢谢!这是我正在寻找的。 – Robben 2014-09-15 16:19:21

5

您可以使用:

''.join(char for char in pharse if char in string.ascii_letters) 

当你for characters in phrase字符实际上是从短语单个字符。循环一个接一个地遍历它们。 string.ascii_letters是一个包含所有字母的字符串 - 短语中的单个字符永远不会等于该字符。这让你的支票 - characters == string.ascii_letters不合逻辑。

您应该检查字符是否为in string.ascii_letters。这告诉我们,如果它是一个ASCII字母。

In [51]: 'a' in 'abcd' 
Out[51]: True 

你的代码还有一个错位的return语句。即使条件成立,它也只会返回一个字符。只有它使用list comprehension,使之更短,更具可读性 -

def allLetters2(phrase): 
    okchars = [] 
    for character in phrase: 
     if character in string.ascii_letters:    
     okchars.append(character) 
    return ''.join(okchars) 

这正是我上面的代码所做的:为你的代码可以重建。

+0

谢谢你的阐述!我如何编写它,而不使用'.append'和'.join'? – Robben 2014-09-12 20:29:50

+1

@Robben在不使用'append'和'join'的情况下编写它的方法就是将字符存储在字符串中。然而这样做效率较低,优雅,所以我建议不要这样做。这从'基本'到'错误' – Korem 2014-09-12 20:33:21

+0

好吧,我会接受你的话。谢谢澄清! – Robben 2014-09-12 20:35:36

0

通常,像filteing /删除或选择的字符集的子集的问题,最好由str.translate处理,如果在适当的意义上使用

代码

def allLetters(st): 
    from string import ascii_letters 
    return st.translate(None, ''.join(set(st)-set(ascii_letters))) 

使用

>>> allLetters("[email protected]") 
'HelloWorldcom'