python字符串切片与列表

时间:2011-08-10 22:42:36

标签: python string list slice

这是我的清单:

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

每个元组的第一项是起始位置,第二项是结束位置。 然后我有一个像这样的字符串:

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

现在,考虑到我的liPos列表,我想通过删除元组中提供的每个起始位置和结束位置(以及包括周围数字)之间的字符来格式化字符串。这是我想要的结果:

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

所以基本上,我想删除2和5之间的字符(包括2和5),然后是8,9(包括8和9)之间的字符,最后是18,22(包括18和22)之间的字符。

有什么建议吗?

4 个答案:

答案 0 :(得分:5)

这假设liPos已经排序,如果sorted(liPos, reverse=True)循环中未使用for

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

这是一个替代方法,它构造一个新的切片元组列表以包含,然后仅使用那些包含的部分连接字符串。

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

为了使这更容易理解,以下是izip_longest生成的切片:

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

答案 1 :(得分:3)

这是一个紧凑的可能性:

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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

这......快速解决了这个问题。可能有更好的方法,但这至少是一个开始。

>>> 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!'