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

时间:2018-05-22 18:06:26

标签: python-3.x insert

我正在尝试解决一个可以最简单建模的问题如下。

我有大量的字母序列。这些字母来自两个列表:(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 

换句话说,一旦成员函后面跟着2个非成员字母,就插入一个'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 个答案:

答案 0 :(得分:0)

生成所有排列将会爆炸您正在检查的内容。你需要改变迭代的方式:

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

通过这种方式,您只需要遍历目标字符串一次,并且您不需要生成排列,这种方法可以扩展到比您的方法更多的前瞻。

答案 1 :(得分:0)

我相信也可以通过正则表达式完成。

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

这将打印A1QFG

答案 2 :(得分:0)

对不起。我错过了。 re.sub可以使用一个可选的count参数,该参数可以在给定的替换次数后停止。

{{1}}

这将打印HB1ODCSL