在 Python 中从字符串中删除辅音

Posted

技术标签:

【中文标题】在 Python 中从字符串中删除辅音【英文标题】:Deleting consonants from a string in Python 【发布时间】:2015-07-11 22:41:13 【问题描述】:

这是我的代码。我不确定我是否需要一个计数器才能工作。答案应该是'iiii'

def eliminate_consonants(x):
        vowels= ['a','e','i','o','u']
        vowels_found = 0
        for char in x:
            if char == vowels:
                print(char)

eliminate_consonants('mississippi')

【问题讨论】:

【参考方案1】:

更正您的代码

if char == vowels: 行是错误的。它必须是if char in vowels:。这是因为您需要检查该特定字符是否存在于元音列表中。除此之外,您需要 print(char,end = '')(在 python3 中)将输出打印为 iiii 全部在一行中。

最终的程序会是这样的

def eliminate_consonants(x):
        vowels= ['a','e','i','o','u']
        for char in x:
            if char in vowels:
                print(char,end = "")

eliminate_consonants('mississippi')

输出将是

iiii

其他方式包括

使用in 字符串

def eliminate_consonants(x):
    for char in x:
        if char in 'aeiou':
            print(char,end = "")

看起来很简单,语句if char in 'aeiou' 检查char 是否存在于字符串aeiou 中。

A list comprehension

 ''.join([c for c in x if c in 'aeiou'])

此列表推导将返回一个列表,其中仅当字符位于 aeiou 中时才包含该字符

A generator expression

''.join(c for c in x if c in 'aeiou')

这个 gen exp 将返回一个生成器,而不是仅当字符在 aeiou 中时才返回字符

Regular Expressions

您可以使用re.findall 仅发现字符串中的元音。代码

re.findall(r'[aeiou]',"mississippi")

将返回在字符串中找到的元音列表,即['i', 'i', 'i', 'i']。所以现在我们可以使用str.join,然后使用

''.join(re.findall(r'[aeiou]',"mississippi"))

str.translatemaketrans

对于这种技术,您需要存储一个映射,将每个非元音匹配到 None 类型。为此,您可以使用string.ascii_lowecase。制作地图的代码是

str.maketrans(i:None for i in string.ascii_lowercase if i not in "aeiou")

这将返回映射。将其存储在变量中(此处为 m 用于地图)

"mississippi".translate(m)

这将从字符串中删除所有非aeiou 字符。

使用dict.fromkeys

您可以将dict.fromkeyssys.maxunicode 一起使用。但记得先import sys

dict.fromkeys(i for i in range(sys.maxunicode+1) if chr(i) not in 'aeiou')

现在使用str.translate

'mississippi'.translate(m)

使用bytearray

正如comments below 中的J.F.Sebastian 所述,您可以使用以下方法创建小写辅音的字节数组

non_vowels = bytearray(set(range(0x100)) - set(b'aeiou'))

使用这个我们可以翻译这个词,

'mississippi'.encode('ascii', 'ignore').translate(None, non_vowels)

这将返回b'iiii'。这可以通过使用decodeb'iiii'.decode("ascii") 轻松转换为str

使用bytes

bytes 返回一个字节对象,是bytearray 的不可变版本。 (它是 Python 3 特有的

non_vowels = bytes(set(range(0x100)) - set(b'aeiou'))

使用这个我们可以翻译这个词,

'mississippi'.encode('ascii', 'ignore').translate(None, non_vowels)

这将返回b'iiii'。这可以通过使用decodeb'iiii'.decode("ascii") 轻松转换为str


时序对比

Python 3

python3 -m timeit -s "text = 'mississippi'*100; non_vowels = bytes(set(range(0x100)) - set(b'aeiou'))" "text.encode('ascii', 'ignore').translate(None, non_vowels).decode('ascii')"
100000 loops, best of 3: 2.88 usec per loop
python3 -m timeit -s "text = 'mississippi'*100; non_vowels = bytearray(set(range(0x100)) - set(b'aeiou'))" "text.encode('ascii', 'ignore').translate(None, non_vowels).decode('ascii')"
100000 loops, best of 3: 3.06 usec per loop
python3 -m timeit -s "text = 'mississippi'*100;d=dict.fromkeys(i for i in range(127) if chr(i) not in 'aeiou')" "text.translate(d)"
10000 loops, best of 3: 71.3 usec per loop
python3 -m timeit -s "import string; import sys; text='mississippi'*100; m = dict.fromkeys(i for i in range(sys.maxunicode+1) if chr(i) not in 'aeiou')" "text.translate(m)"
10000 loops, best of 3: 71.6 usec per loop
python3 -m timeit -s "text = 'mississippi'*100" "''.join(c for c in text if c in 'aeiou')"
10000 loops, best of 3: 60.1 usec per loop
python3 -m timeit -s "text = 'mississippi'*100" "''.join([c for c in text if c in 'aeiou'])"
10000 loops, best of 3: 53.2 usec per loop
python3 -m timeit -s "import re;text = 'mississippi'*100; p=re.compile(r'[aeiou]')" "''.join(p.findall(text))"
10000 loops, best of 3: 57 usec per loop

时间排序

translate (bytes)    |  2.88
translate (bytearray)|  3.06
List Comprehension   | 53.2
Regular expressions  | 57.0
Generator exp        | 60.1
dict.fromkeys        | 71.3
translate (unicode)  | 71.6

如您所见,使用bytes 的最终方法是最快的。


Python 3.5

python3.5 -m timeit -s "text = 'mississippi'*100; non_vowels = bytes(set(range(0x100)) - set(b'aeiou'))" "text.encode('ascii', 'ignore').translate(None, non_vowels).decode('ascii')"
100000 loops, best of 3: 4.17 usec per loop
python3.5 -m timeit -s "text = 'mississippi'*100; non_vowels = bytearray(set(range(0x100)) - set(b'aeiou'))" "text.encode('ascii', 'ignore').translate(None, non_vowels).decode('ascii')"
100000 loops, best of 3: 4.21 usec per loop
python3.5 -m timeit -s "text = 'mississippi'*100;d=dict.fromkeys(i for i in range(127) if chr(i) not in 'aeiou')" "text.translate(d)"
100000 loops, best of 3: 2.39 usec per loop
python3.5 -m timeit -s "import string; import sys; text='mississippi'*100; m = dict.fromkeys(i for i in range(sys.maxunicode+1) if chr(i) not in 'aeiou')" "text.translate(m)"
100000 loops, best of 3: 2.33 usec per loop
python3.5 -m timeit -s "text = 'mississippi'*100" "''.join(c for c in text if c in 'aeiou')"
10000 loops, best of 3: 97.1 usec per loop
python3.5 -m timeit -s "text = 'mississippi'*100" "''.join([c for c in text if c in 'aeiou'])"
10000 loops, best of 3: 86.6 usec per loop
python3.5 -m timeit -s "import re;text = 'mississippi'*100; p=re.compile(r'[aeiou]')" "''.join(p.findall(text))"
10000 loops, best of 3: 74.3 usec per loop

时间排序

translate (unicode)  |  2.33
dict.fromkeys        |  2.39
translate (bytes)    |  4.17
translate (bytearray)|  4.21
List Comprehension   | 86.6
Regular expressions  | 74.3
Generator exp        | 97.1

【讨论】:

谢谢! :) 感谢快速响应。 :) :) 您能否告诉我如何在 Python 2.7 中将输出全部打印在一行中:print(char,end = "") 似乎仅适用于 Paython 3。谢谢。 @JoeR print char, 在 py2 中(注意尾随逗号) vowels_found = 0 是什么意思? 如果您需要速度;使用字节并调用bytestring.translate(None, non_vowels)【参考方案2】:

你可以试试这样的pythonic方式,

In [1]: s = 'mississippi'
In [3]: [char for char in s if char in 'aeiou']
Out[3]: ['i', 'i', 'i', 'i']

功能;

In [4]: def eliminate_consonants(x):
   ...:     return ''.join(char for char in x if char in 'aeiou')
   ...: 

In [5]: print(eliminate_consonants('mississippi'))
iiii

【讨论】:

错误!我更喜欢return ''.join([char for char in x if char in 'aeiou'])。直接且易于理解:) @BhargavRao 建立您的中间列表既不必要又昂贵。你应该删除那些[]。另一种选择是''.join(filter('aeiou'.__contains__, s))。我测试了一个 1000 万个小写字母字符串,Bhargav 的方式用了 2.16 秒,我的用了 1.47 秒,Bhargav 没有创建中间列表用了 1.25 秒。 @StefanPochmann 感谢好友提供的信息。我会更新my答案。 @BhargavRao 那里的更新也很好,但我的意思是您的评论。只需使用 ''.join(char ... 'aeiou') 而不使用 []【参考方案3】:

== 测试是否相等。您正在查看列表“元音”中的字符串中是否存在任何字符。为此,您可以简单地使用in,如下所示。

此外,我看到您有一个“vowels_found”变量,但没有使用它。下面是一个如何解决这个问题的例子:

def eliminate_consonants(x):
    vowels= ['a','e','i','o','u']
    vowels_found = 0
    for char in x:
        if char in vowels:
            print(char)
            vowels_found += 1

    print "There are", vowels_found, "vowels in", x

eliminate_consonants('mississippi')

您的输出将是:

i
i
i
i
There are 4 vowels in mississippi

【讨论】:

充其量,这是评论,而不是答案。

以上是关于在 Python 中从字符串中删除辅音的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中从字节字符串中删除前 20 个字节的最快方法是啥?

创建一个删除元音的函数

在 Python 语言中从列表元素中删除撇号

创建一个 Python 函数,该函数将为字符计数的元组创建一个字典,分配给元音、辅音或其他的键

如何在 Python 3.9 中从 re.sub 中删除反斜杠

如何在 Swift 中从字符串中删除引号?