【问题标题】:Consecutive values in strings, getting indices字符串中的连续值,获取索引
【发布时间】:2017-11-22 08:48:05
【问题描述】:

以下是长度约为+1000的python字符串。

string1 = "XXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBB........AAAAXXXXX"
len(string1)  ## 1311

我想知道连续 X 的结束和非 X 字符开始的索引。从左到右读取这个字符串,第一个非 X 字符在索引位置 22,从右边开始的第一个非 X 字符在索引位置 1306。

如何找到这些索引?

我的猜测是:

for x in string1:
    if x != "X":
        print(string.index(x))

这个问题是它输出所有不是 X 的索引。它没有给我连续 X 结束的索引。

对我来说更令人困惑的是如何“检查”连续的 X。假设我有这个字符串:

string2 = "XXXXAAXAAAAAAAAAAAAAAABBBBBBBBBBBBBB........AAAAXXXXX"

在这里,连续的 X 在索引 4 处结束,而不是索引 7。我如何检查前面的几个字符是否真的不再连续?

【问题讨论】:

  • 您在寻找所有连续的 X 吗?在您的示例中,字符串中有不同的连续 X 序列。另外,你究竟是如何收集它们的?您的预期输出结构是什么?
  • @idjaw 只是一个简单的字符串。我想知道连续 X 的结束位置。给出了字符串。输出应该只是不再有连续 X 的索引。
  • 好的,但是例如在你的第一个字符串中,开头有一个 X 序列,但是在同一个字符串的末尾有另一个 X 序列。你只是在寻找第一个吗?
  • @idjaw 不,我想要两个索引。在这些字符串中,连续的 X 仅位于开头和结尾。抱歉——我没有说清楚。
  • 对。和我想的一样。那么,你想如何显示这个?您是否希望以 [(0, 10), (200, 224)] 之类的结构收集这些信息?您可能也应该在问题中编辑其细节。

标签: python string indexing splice


【解决方案1】:

使用正则表达式,拆分Xs 的第一组和最后一组,获取它们的长度来构造索引。

import re

mystr = 'XXXXAAXAAAAAAAAAAAAAAABBBBBBBBBBBBBB........AAAAXXXXX'
xs = re.split('[A-W|Y-Z]+', mystr)
indices = (len(xs[0]), len(mystr) - len(xs[-1]) - 1)
# (4, 47)

我只需要索引的输出。然后我会把它们放在randint(first_index, second_index)

可以像这样将索引传递给函数

randint(*indices)

但是,我怀疑您想使用randint(first_index, last_index) 的输出从中间选择一个随机字符,这将是一个更短的选择。

from random import choice
randchar = choice(mystr.strip('X'))

【讨论】:

    【解决方案2】:

    如果我理解你的问题,你就这样做:

    def getIndexs(string):
      lst =[]
      flag = False
      for i, char in enumerate(string):
    
        if char == "x":
          flag = True
    
        if ((char != "x") and flag):
          lst.append(i-1)
          flag = False
    
    
      return lst
    
    
    print(getIndexs("xxxxbbbxxxxaaaxxxbb"))
    

    [3,10,16]

    【讨论】:

      【解决方案3】:

      如果序列如您所说,仅在字符串的开头和结尾,则一个简单的循环/反向循环就足够了:

      string1 = "XXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBB........AAAAXXXXX"
      
      left_index = 0
      for char in string1:
          left_index += 1
          if char != "X":
               break
      
      right_index = len(string1)
      for char in reversed(string1):
          if char != "X":
               break
          right_index -= 1
      
      print(left_index)  # 22
      print(right_index)  # 65
      

      【讨论】:

        【解决方案4】:

        正则表达式可以lookahead 并识别与模式不匹配的字符:

        >>>[match.span() for match in re.finditer(r'X{2,}((?=[^X])|$)', string2)] [(0, 4), (48, 53)]

        分解:

        • X - 我们匹配的字符
        • {2,} - 需要至少连续看到两个才能考虑匹配
        • ((?=[^X])|$) - 两个条件将满足匹配
          • (?=[^X]) - 向前看 X
          • $ - 字符串的结尾

        因此,finditer 返回每个有多个 X 的实例,后跟一个非 X 或行尾。 match.span() 从字符串中提取每个匹配的位置信息。

        【讨论】:

          【解决方案5】:

          这将为您提供第一个索引和最后一个索引(非“X”字符)。

          s = 'XXABCDXXXEFGHXXXXX'
          
          first_index = len(s) - len(s.lstrip('X'))
          last_index = len(s.rstrip('X')) - len(s) - 1
          

          打印 first_index, last_index

          2 -6

          工作原理:

          对于 first_index:

          我们去掉字符串开头的所有“X”字符。找出原始字符串和缩短字符串之间的长度差异为我们提供了第一个非“X”字符的索引。

          对于 last_index:

          同样,我们去掉字符串末尾的“X”字符。我们还从差值中减去 1,因为 Python 中的反向索引从 -1 开始。

          注意:

          如果你只是想在 first_index 和 last_index 之间随机选择一个字符,你可以这样做:

          import random
          shortened_s = s.strip('X')
          random.choice(shortened_s)
          

          【讨论】:

          • 对于first_index & last_index,如果分别使用lstrip & rstrip,而不是strip,表达式会更简单。
          • @HaleemurAli 对,这要简单得多!
          猜你喜欢
          • 1970-01-01
          • 2021-07-19
          • 1970-01-01
          • 1970-01-01
          • 2012-06-29
          • 2011-11-21
          • 2016-02-16
          • 2017-07-28
          • 2023-03-27
          相关资源
          最近更新 更多