【问题标题】:python string slicing with a listpython字符串切片与列表
【发布时间】:2011-10-24 12:45:49
【问题描述】:

这是我的清单:

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

有什么建议吗?

【问题讨论】:

  • 您是否在想要的答案中有错误?鉴于您的脂质体,不应该是“我会回答我的问题!” ?
  • 哈哈,是的,抱歉我弄错了,但我编辑了它:)

标签: python string list slice


【解决方案1】:

这假定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)]

【讨论】:

  • 我有一个大字符串,它无法按我想要的方式打印源。虽然我还没有尝试过你的第二次见面。
【解决方案2】:
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】:

    这是一种紧凑的可能性:

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

    【讨论】:

      【解决方案4】:

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

      >>> 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() 的参数从列表 [] 更改为生成器 () 会有所帮助。
      猜你喜欢
      • 2020-11-27
      • 1970-01-01
      • 2016-10-27
      • 2023-04-09
      • 2014-07-21
      • 2012-02-15
      • 1970-01-01
      • 2016-07-21
      相关资源
      最近更新 更多