在 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.translate
和 maketrans
对于这种技术,您需要存储一个映射,将每个非元音匹配到 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.fromkeys
与sys.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'
。这可以通过使用decode
即b'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'
。这可以通过使用decode
即b'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 函数,该函数将为字符计数的元组创建一个字典,分配给元音、辅音或其他的键