我试图使用Python从字符串中删除特定字符。这是我现在使用的代码。不幸的是,它似乎对字符串没有做任何事情。

for char in line:
    if char in " ?.!/;:":
        line.replace(char,'')

我如何正确地做到这一点?


当前回答

在Python 3.5中

例如,

os.rename(file_name, file_name.translate({ord(c): None for c in '0123456789'}))

从字符串中删除所有数字

其他回答

这里有一些可能的方法来完成这个任务:

def attempt1(string):
    return "".join([v for v in string if v not in ("a", "e", "i", "o", "u")])


def attempt2(string):
    for v in ("a", "e", "i", "o", "u"):
        string = string.replace(v, "")
    return string


def attempt3(string):
    import re
    for v in ("a", "e", "i", "o", "u"):
        string = re.sub(v, "", string)
    return string


def attempt4(string):
    return string.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "")


for attempt in [attempt1, attempt2, attempt3, attempt4]:
    print(attempt("murcielago"))

附注:在使用" ?.!/;:"的例子中使用元音…是的,“murcielago”在西班牙语里是蝙蝠的意思…有趣的单词,因为它包含了所有的元音:)

PS2:如果你对性能感兴趣,你可以用一个简单的代码来衡量这些尝试:

import timeit


K = 1000000
for i in range(1,5):
    t = timeit.Timer(
        f"attempt{i}('murcielago')",
        setup=f"from __main__ import attempt{i}"
    ).repeat(1, K)
    print(f"attempt{i}",min(t))

在我的盒子里,你会得到:

attempt1 2.2334518376057244
attempt2 1.8806643818474513
attempt3 7.214925774955572
attempt4 1.7271184513757465

因此,对于这个特定的输入,尝试4似乎是最快的。

令我惊讶的是,还没有人推荐使用内置的过滤功能。

    import operator
    import string # only for the example you could use a custom string

    s = "1212edjaq"

假设我们想过滤掉所有不是数字的东西。使用过滤器内置方法“…等效于生成器表达式(item for item在可迭代if函数(item)中)"[Python 3 Builtins: Filter]

    sList = list(s)
    intsList = list(string.digits)
    obj = filter(lambda x: operator.contains(intsList, x), sList)))

在Python 3中返回

    >>  <filter object @ hex>

要得到打印的字符串,

    nums = "".join(list(obj))
    print(nums)
    >> "1212"

我不确定过滤器在效率方面的排名,但在做列表理解等时,知道如何使用是一件好事。

更新

从逻辑上讲,既然过滤器可以工作,你也可以使用列表理解,从我所读到的,它应该更有效,因为lambdas是编程函数世界的华尔街对冲基金经理。另一个优点是它是一个单行程序,不需要任何导入。例如,使用上面定义的字符串's',

      num = "".join([i for i in s if i.isdigit()])

就是这样。返回值将是原始字符串中所有数字组成的字符串。

如果你有一个特定的可接受/不可接受字符列表,你只需要调整列表理解的' If '部分。

      target_chars = "".join([i for i in s if i in some_list]) 

或者,

      target_chars = "".join([i for i in s if i not in some_list])

提问者几乎就说到了。像Python中的大多数事情一样,答案比您想象的要简单。

>>> line = "H E?.LL!/;O:: "  
>>> for char in ' ?.!/;:':  
...  line = line.replace(char,'')  
...
>>> print line
HELLO

你不需要做嵌套的if/for循环,但你确实需要单独检查每个字符。

>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if  c not in '?:!/;' )
'abc#@efg12'

这是我的Python 2/3兼容版本。因为翻译api已经改变了。

def remove(str_, chars):
    """Removes each char in `chars` from `str_`.

    Args:
        str_: String to remove characters from
        chars: String of to-be removed characters

    Returns:
        A copy of str_ with `chars` removed

    Example:
            remove("What?!?: darn;", " ?.!:;") => 'Whatdarn'
    """
    try:
        # Python2.x
        return str_.translate(None, chars)
    except TypeError:
        # Python 3.x
        table = {ord(char): None for char in chars}
        return str_.translate(table)