代码之家  ›  专栏  ›  技术社区  ›  twhale

如何确定一个列表中的两个元素是否连续出现在一个字符串中?蟒蛇

  •  0
  • twhale  · 技术社区  · 7 年前

    我正试图解决一个问题,这个问题的模型最简单的如下。

    我收集了大量的字母序列。这些字母来自两个列表:(1)成员列表(2)非成员列表。序列具有不同的组成和长度(例如AQFG、CCPFAKXZ、HBodCSL等)。我的目标是将数字“1”插入到这些序列中,当任何“成员”后接任何两个“非成员”时:

    Rule 1: Insert '1' after the first member letter that is followed 
    by 2 or more non-members letters.
    Rule 2: Insert not more than one '1' per sequence.
    
    The 'Members': A, B, C, D
    'Non-members': E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z 
    

    换句话说,一旦一个成员字母后面跟着两个非成员字母,就插入一个“1”。总共,每个序列只插入一个“1”。我正在努力实现的例子如下:

    AQFG        --->   A1QFG
    CCPFAKXZ    --->   CC1PFAKXZ
    BDDCCA      --->   BDDCCA1
    HBODCSL     --->   HBODC1SL
    ABFCC       --->   ABFCC
    ACKTBB      --->   AC1KTBB # there is no '1' to be inserted after BB 
    

    我假设代码是这样的:

    members = ['A','B','C','D']
    non_members = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N',
    'O','P','Q','R','S','T','U','V','W','X','Y','Z']
    strings = ['AQFG', 'CCPFAKXZ', 'BDDCCA', 'HBODCSL', 'ABFCC']
    
    for i in members:
        if i in strings:
            if member is followed by 2 non-members: # Struggling here
                i.insert(index_member, '1')            
            return i
    return ''
    

    编辑

    我发现一种解决方案是生成两个“非成员”项的所有排列的列表,使用 itertools.permutations(non_members, 2) ,然后测试它们是否存在于字符串中。

    但对于这个问题有更优雅的解决方案吗?

    3 回复  |  直到 7 年前
        1
  •  0
  •   esoterik    7 年前

    生成所有排列将分解正在检查的内容的数量。您需要更改迭代的方式,例如:

    members = ...
    non_members = ...
    s = 'AQFG'
    out = ""
    look = 2
    for i in range(len(s)-look):
        out += s[i]
        if (s[i] in members) & \
           (s[i+1] in non_members) & \
           (s[i+2] in non_members):
               out += '1' + s[i+1:]
               break
    

    这样,您只需要遍历目标字符串一次,而不需要生成排列,该方法可以扩展到比您的方法更具前瞻性的地方。

        2
  •  0
  •   Bharath Bharath    7 年前

    我相信也可以通过regex来实现。

      s = 'AQFG'
      x = re.sub(r'([ABCD])([EFGHIJKLMNOPQRSTUVWXYZ])',r'\g<1>1\2',s)
      print(x)
    

    这将打印a1qfg

        3
  •  0
  •   Bharath Bharath    7 年前

    对不起的。我错过了。re.sub可以接受一个可选的count参数,在进行给定数量的替换之后,该参数可以停止。

    s = 'HBODCSL'
    x = re.sub(r'([ABCD]+)([EFGHIJKLMNOPQRSTUVWXYZ])',r'\g<1>1\2',s,count=1)
    print(x)
    

    这将打印HB1ODCSL

    推荐文章