[英]python string slicing with a list
這是我的清單:
liPos = [(2,5),(8,9),(18,22)]
每個元組的第一項是開始 position,第二項是結束 position。 然后我有一個這樣的字符串:
s = "I hope that I will find an answer to my question!"
現在,考慮到我的liPos
列表,我想通過刪除元組中提供的每個開始和結束 position (包括周圍的數字)之間的字符來格式化字符串。 這是我想要的結果:
"I tt I will an answer to my question!"
所以基本上,我想刪除 2 到 5 之間的字符(包括 2 和 5),然后是 8,9 之間(包括 8 和 9),最后是 18,22 之間(包括 18 和 22)。
有什么建議嗎?
這假設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)]
這是一種緊湊的可能性:
"".join(s[i] for i in range(len(s)) if not any(start <= i <= end for start, end in liPos))
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
這......是一個快速解決問題的方法。 可能有更好的方法,但至少是一個開始。
>>> 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!'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.