开发者

python string slicing with a list

Here is my list:

liPos = [(2,5),(8,9),(18,22)]

The first item of each tuple is the starting position and the second is the ending position. Then I have a string like this:

s = "I hope that I will find an answer to my question!"

Now, considering my li开发者_如何学CPos list, I want to format the string by removing the chars between each starting and ending position (and including the surrounding numbers) provided in the tuples. Here is the result that I want:

"I tt I will an answer to my question!"

So basically, I want to remove the chars between 2 and 5 (including 2 and 5), then between 8,9 (including 8 and 9) and finally between 18,22 (including 18 and 22).

Any suggestion?


This assumes that liPos is already sorted, if it is not used sorted(liPos, reverse=True) in the for loop.

liPos = [(2,5),(8,9),(18,22)]
s = "I hope that I will find an answer to my question!"
for begin, end in reversed(liPos):
    s = s[:begin] + s[end+1:]

print s

Here is an alternative method that constructs a new list of slice tuples to include, and then joining the string with only those included portions.

from itertools import chain, izip_longest
# second slice index needs to be increased by one, do that when creating liPos
liPos = [(a, b+1) for a, b in liPos]
result = "".join(s[b:e] for b, e in izip_longest(*[iter(chain([0], *liPos))]*2))

To make this slightly easier to understand, here are the slices generated by izip_longest:

>>> list(izip_longest(*[iter(chain([0], *liPos))]*2))
[(0, 2), (6, 8), (10, 18), (23, None)]


liPos = [(2,5),(8,9),(18,22)]
s = "I hope that I will find an answer to my question!"

exclusions = set().union(* (set(range(t[0], t[1]+1)) for t in liPos) )
pruned = ''.join(c for i,c in enumerate(s) if i not in exclusions)

print pruned


Here is one, compact possibility:

"".join(s[i] for i in range(len(s)) if not any(start <= i <= end for start, end in liPos))


This ... is a quick stab at the problem. There may be a better way, but it's a start at least.

>>> liPos = [(2,5),(8,9),(18,22)]
>>>
>>> toRemove = [i for x, y in liPos for i in range(x, y + 1)]
>>>
>>> toRemove
[2, 3, 4, 5, 8, 9, 18, 19, 20, 21, 22]
>>>
>>> s = "I hope that I will find an answer to my question!"
>>>
>>> s2 = ''.join([c for i, c in enumerate(s) if i not in toRemove])
>>>
>>> s2
'I  tt I will an answer to my question!'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜