如何在Python中用字符串替换字符集或字符组

如何在Python中用字符串替换字符集或字符组,python,python-3.x,Python,Python 3.x,我试图制作一个简单的脚本来替换文本中出现的某些组或字符集(或字符串集) 在本例中,我将尝试用特定字符串替换所有字母“a、e、I、o、u” 我的剧本: def replace_all(text, repl): text1 = text.replace("a", repl) text2 = text1.replace("e", repl) text3 = text2.replace("i", repl) text4 = text3.replace("o", repl)

我试图制作一个简单的脚本来替换文本中出现的某些组或字符集(或字符串集)

在本例中,我将尝试用特定字符串替换所有字母“a、e、I、o、u”

我的剧本:

def replace_all(text, repl):
    text1 = text.replace("a", repl)
    text2 = text1.replace("e", repl)
    text3 = text2.replace("i", repl)
    text4 = text3.replace("o", repl)
    text5 = text4.replace("u", repl)
    return text5
有没有更简单的方法?如果我需要替换更大的字符或字符串组,该怎么办?像这样把它拴起来似乎并没有什么效果


这可能是一个原始的问题。然而,我仍处于学习阶段,所以我可能会在以后的课程中得到它。提前感谢您的建议

这是一个很好的地方:

这将适用于您问题中替换单个字符的情况。如果要替换一组较长的字符串,请执行以下操作:

def replace_all(text, to_replace, replacement):
    pattern = '|'.join(to_replace)
    return re.sub(pattern, replacement, text)

>>> replace_all('this is a thing', ['thi','a'], 'x')
'xs is x xng'

据我所知,有三种不同的方法可以做到这一点,它们都比你的方法短:

  • 对循环使用
  • 使用
    生成器理解
  • 使用
    正则表达式

首先,使用
for循环
。这可能是对代码最直接的改进,基本上只是将
5行减少为
。将
替换为
2行:

def replace_all(text, repl):
    for c in "aeiou":
        text = text.replace(c, repl)
    return text

您还可以使用
generator comprehension
,结合
str.join
方法,在一行中完成此操作。这会更快(如果这很重要的话),因为它的复杂性
O(n)
,因为我们将遍历每个字符并对其求值一次(第一种方法是复杂性
O(n^5)
,因为Python将针对不同的替换循环
文本
五次)

因此,这种方法很简单:

def replace_all(text, repl):
    return ''.join(repl if c in 'aeiou' else c for c in text)

最后,我们可以使用替换集合中的所有字符:
[aeiou]
为文本
repl
。这是最短的解决方案,我可能会推荐:

import re
def replace_all(text, repl):
    return re.sub('[aeiou]', repl, text)

正如我在开始时所说的,所有这些方法都完成了任务,因此我没有必要提供单独的测试用例,但它们确实可以工作,如本测试中所示:

>>> replace_all('hello world', 'x')
'hxllx wxrld'

更新

我注意到了一种新方法:
str.translate

>>> {c:'x' for c in 'aeiou'}
{'a': 'x', 'e': 'x', 'i': 'x', 'o': 'x', 'u': 'x'}
>>> 'hello world'.translate({ord(c):'x' for c in 'aeiou'})
'hxllx wxrld'

此方法也是
O(n)
,因此与前两种方法一样有效。

因此,您所做的是完全有效的,但是有更好的方法

下面是一些解决方案,运行时占用了100000个循环

主要签名: 目标是要替换的字符,repl是替换字符

def replace_all(text, targets=['a', 'e', 'i', 'o', 'u'], repl='_'):
    text = # Something here to swap characters as an array
    return ''.join(text) # Stitch it back together
拜特利 是一个可变的数据结构,其中包含字符本身的列表。作为一种数据结构,它似乎是一种理想的选择,python中的字符串是不可变的,这可以避免不断的构造/破坏

[chr(c) if chr(c) not in targets else repl for c in bytearray(text, 'utf-8')]
运行速度为0.365

无障碍 这在一个简单的列表上操作,列表本身是可变的,但是字符是字符串,因此这里对技术上不可变的结构进行了一些修改

[c if c not in targets else repl for c in text]
以0.179的速度运行

地图 这将函数映射到字符串中的每个字符

map(lambda c: c if c not in targets else repl, text) 

以0.265运行

str.translate()如何?为什么这是个好主意还是个坏主意?@PoeteMaudit以前从未遇到过这种方法!查看我的更新。我不知道你所说的“好”或“坏”是什么意思——你可以做任何你想做的事情,只要它是有效率的,我希望这种方法是有效的。我很惊讶你以前没有遇到过。你也可以看到这个:。
map(lambda c: c if c not in targets else repl, text)