从字符串中删除字符。

4

我需要一个函数remove(),用于从字符串中删除字符。

这是我的第一种方法:

def remove(self, string, index):
    return string[0:index] + string[index + 1:]

def remove_indexes(self, string, indexes):
    for index in indexes:
        string = self.remove(string, index)
    return string

我希望在数组中删除指定索引的元素,但一旦删除一个字符,整个索引都会改变。是否有更Pythonic的方法来实现这一点?最好的实现方式应该是:

"hello".remove([1, 2])
4个回答

3

我不知道“Pythonic”的方法,但是你可以实现这个功能。如果你能确保在remove_indexes中索引总是有序的,那么你可以这样做。

def remove_indexes(self, string, indexes):
    for index in indexes.reverse():
        string = self.remove(string, index)
    return string

如果您无法确保这一点,那就只需要执行此操作。
def remove_indexes(self, string, indexes):
    for index in indexes.sort(reverse=True):
        string = self.remove(string, index)
    return string

2
我认为以下代码适用于您。它将删除您想要从字符串中删除的索引,并返回由剩余索引组成的连接字符串。
def remove_indexes(string,indexes):
    return "".join([string[i] for i in range(len(string)) if i not in indexes])

remove_indexes("hello",[1,2])

1
最Pythonic的方法是使用正则表达式。您使用索引的方法存在风险,因为传入的字符串可能具有可变长度,因此您可能会无意中删除字符串的某些部分。
假设您想从字符串中删除所有数字。
import re

s = "This is a string with s0m3 numb3rs in it1 !"
num_reg = re.compile(r"\d+")  # catches all digits 0-9
re.sub(num_reg , "**", s)  # substitute numbers in `s` with "**"
>>> "This is a string with s**m** numb**rs in it** !"

通过这种方式,您可以定义一个在字符串中可能经常出现的通用表达式(称为“正则表达式”或“regex”),并且可以快速而可靠地替换字符串中该正则表达式的所有实例。

1
您不能向内置类型添加属性,否则会出现如下错误:
TypeError: can't set attributes of built-in/extension type 'str'

你可以创建一个继承自 strclass 并添加这个方法:
class String(str):
    def remove(self, index):
        if isinstance(index, list):
            # order the index to remove the biggest first
            for i in sorted(index, reverse=True):
                self = self.remove(i)
            return self
        return String(self[0:index] + self[index + 1:])

s = String("hello")
print(s.remove([0, 1]))

如果您想要在原地进行更改,您需要创建一个新类型,例如:

 class String:
    def __init__(self, value):
        self._str = value

    def __getattr__(self, item):
        """ delegate to str"""
        return getattr(self._str, item)

    def __getitem__(self, item):
        """ support slicing"""
        return String(self._str[item])

    def remove(self, indexex):
        indexes = indexex if isinstance(indexex, list) else [indexex]
        # order the index to remove the biggest first
        for i in sorted(indexes, reverse=True):
            self._str = self._str[0:i] + self._str[i + 1:]
        # change in place should return None
        return None

    def __str__(self):
        return str(self._str)

    def __repr__(self):
        return repr(self._str)


s = String("hello")
s.remove([0, 1])
print(s.upper())    # delegate to str class
print(s[:1])    # support slicing
print(list(x for x in s))    # it's iterable

但仍然缺少其他类似于真实str类的魔法方法,例如__add__, __mult__,......

如果您想要一个像str一样的类,但具有可以更改实例本身的remove方法,则需要创建自己的可变类型str原始不可变类型self = self.remove(i)不会真正更改变量,因为它只是将self参数的引用更改为另一个object,但引用s仍指向由String("hello")创建的相同对象。


i.remove([0, 1]) print(i)``` 这段代码无法正常工作。因为 `self = self.remove(i)` 没有修改变量。 - moe asal
抱歉有额外的代码,关键是你不能向“内置的str”类型添加属性,因此也无法添加任何方法。 - Charif DZ
抱歉,我应该返回字符串类型。 - Charif DZ
str 是原始类型,你无法直接在原地修改它们。 - Charif DZ
希望这可以帮到你,问题在于字符串是不可变的,你需要创建一个像字符串一样的新类,你可以看看我的编辑,但也许有比这更好的解决方案,我现在真的不知道。 - Charif DZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接