使用列表对Python字符串进行切片

4

这是我的清单:

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

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

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

现在,考虑到我的列表,我想通过删除元组中提供的每个起始和结束位置之间的字符(包括周围的数字)来格式化字符串。这是我想要的结果:
"I tt I will an answer to my question!"

基本上,我想删除2和5之间的字符(包括2和5),然后在8、9之间(包括8和9)和最后在18、22之间(包括18和22)删除字符。 有什么建议吗?

1
你在期望的答案中犯了一个错误吗?考虑到你的锂聚合物电池,应该是“我会得到我的问题的答案!”。 - James Tauber
哈哈,是的,抱歉我犯了一个错误,不过我已经修改好啦 :) - Shaokan
4个回答

5
这里假设liPos已经排序,如果没有排序,请在for循环中使用sorted(liPos, reverse=True)
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)]

我有一个很长的字符串,但它无法按照我的要求打印源代码。虽然我还没有尝试过你的第二种方法。 - Shaokan

3

这里有一个简洁的可能性:

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

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

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

这种方法存在一些明显的缺点。首先,对于需要删除的大量索引,它会变得非常_缓慢_。使用不同的容器类型来存储“toRemove”可以加快速度。此外,它可能会占用比必要更多的内存,但是将传递给 ''.join() 的参数从列表[]更改为生成器()可以解决这个问题。 - g.d.d.c

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