简体   繁体   English

python 字符串切片带列表

[英]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.每个元组的第一项是开始 position,第二项是结束 position。 Then I have a string like this:然后我有一个这样的字符串:

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

Now, considering my liPos 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.现在,考虑到我的liPos列表,我想通过删除元组中提供的每个开始和结束 position (包括周围的数字)之间的字符来格式化字符串。 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).所以基本上,我想删除 2 到 5 之间的字符(包括 2 和 5),然后是 8,9 之间(包括 8 和 9),最后是 18,22 之间(包括 18 和 22)。

Any suggestion?有什么建议吗?

This assumes that liPos is already sorted, if it is not used sorted(liPos, reverse=True) in the for loop.这假设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

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 :为了让这更容易理解,这里是izip_longest生成的切片:

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM