Python: removing a substring by index

I have the following pretty simple snippet:

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

This function takes a string sand removes everything s[start:end]from swhere the index pairs (start, end)are listed blocks.

Is there a built-in function somewhere that does the same?


Update: There is an assumption in my code:

  • Blocks
  • sorted by first index in ascending order (performed list.sort()locally)

As for the fact that blocks can overlap, in my case I guarantee that they are not up to the function call. But for fun, we can also assume that they are :)

+4
source share
5 answers

blocks , exclude. , exclude. set , ( ).

exclude

, :

blocks = [(5, 7), (2, 4), (6, 10)]

:

exclude = {2, 3, 5, 6, 7, 8, 9}

exclude = set()
for block in blocks:
    exclude.update(range(*block))

. , , , , , . , , , .

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))

: delete_substring_blocks

, delete_substring_blocks, delete_blocks:

def delete_substring_blocks(s, blocks):
    return ''.join(delete_blocks(s, blocks))
+3

, , .

- :

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 orig_str
  '''
  for start, end in reversed(sorted(blocks)):
    s = s[:start] + s[end:]
  return s
0

, , .

, , :

def delete_substring_blocks(s, blocks):
    return ''.join(
        [c for i, c in enumerate(s) 
         if not any(blk for blk in blocks 
                    if i >= blk[0] and i < blk[1])])

, , , .

:

>>> delete_substring_blocks(
        "hello there how are you", 
        [[0, 3], [7, 9], [7, 10]])
'lo te how are you'

, , :

def delete_substring_blocks(s, blocks):
    def check_pos(i):
        return not any(1 for start, end in blocks 
                       if i >= start and i < end)

    return ''.join([c for i, c in enumerate(s) 
                    if check_pos(i)])
0

, . :

def delete_substring_blocks(s, blocks):
    # create a bitmap with False for characters to be deleted
    preserve = [True] * len(s)
    for i, j in blocks:
        preserve[i:j] = False

    result = []
    for i, c in enumerate(s):
        if preserve[i]:
            result.append(c)

    return ''.join(result)
0

No. What you are asking for is quite specific. You can easily select one line if you want to specify the parts of the line that you want to save (as opposed to deleting).

>>> string = 'my long string'
>>> ''.join([string[s:e] for s, e in [(0,3), (8, 14)]])
'my string'
-1
source

Source: https://habr.com/ru/post/1618957/


All Articles