Python:按索引删除子字符串

Mai*_*Mai 5 python string

我有以下相当简单的片段:

def delete_substring_blocks(s, blocks):                                                                             
  '''                                                                                                                   
      s: original input string                                                                                   
      blocks: list of indices (start, end) to be deleted                                                                

      return string `out` where blocks are deleted from s                                                      
  '''                                                                                                                   
  out = ''                                                                                                              
  p = 0                                                                                                                 
  for start, end in blocks:                                                                                             
      out += s[p:start]                                                                                               
      p = end                                                                                                           
  out += s[p:]                                                                                                        
  return out
Run Code Online (Sandbox Code Playgroud)

此函数接受一个字符串s并s[start:end]从 中删除所有内容s,其中(start, end)在列表中给出了索引对blocks。

某处是否有一个内置函数可以做同样的事情?


更新:我的代码中有一个假设:

  1. 块按升序按第一个索引排序(由list.sort()就地完成)

至于块是否可以重叠,在我的用例中,我确保它们在调用函数之前不会重叠。但为了好玩,我们也可以假设他们这样做。

Hai*_* Vu 5

我的方法转化blocks为一组我称之为的索引exclude。之后,循环遍历字符串并排除索引在集合中的那些字符exclude。我使用集合而不是列表,因为它可以很好地处理重复项(在重叠范围的情况下)。

构建exclude集合

给定一个无序的、可能重叠的范围列表:

blocks = [(5, 7), (2, 4), (6, 10)]
Run Code Online (Sandbox Code Playgroud)

我想把它转换成:

exclude = {2, 3, 5, 6, 7, 8, 9}
Run Code Online (Sandbox Code Playgroud)

如何:

exclude = set()
for block in blocks:
    exclude.update(range(*block))
Run Code Online (Sandbox Code Playgroud)

把它们放在一起

这是我的代码,最后还有一个小例子。请注意,我选择重命名该函数,因为该函数足够通用,可以处理字符串、列表、元组和其他可迭代对象,而不仅仅是字符串。另外,因为该函数返回一个列表,所以在处理字符串时,我们需要将字符列表重新连接在一起。

def delete_blocks(iterable, blocks):                                                                             
    exclude = set()
    for block in blocks:
        exclude.update(range(*block))
    return [cell for i, cell in enumerate(iterable) if i not in exclude]

# Try it out
test_string = '0123456789abc'
blocks = [(5, 7), (2, 4), (6, 10)]
result = ''.join(delete_blocks(test_string, blocks))

print('Before: {!r}'.format(test_string))
print('Blocks:', blocks)
print('After: {!r}'.format(result))
Run Code Online (Sandbox Code Playgroud)

更新:实施delete_substring_blocks

为了真正回答麦的问题,我delete_substring_blocks使用以下方法实现delete_blocks:

def delete_substring_blocks(s, blocks):
    return ''.join(delete_blocks(s, blocks))
Run Code Online (Sandbox Code Playgroud)