生成由一定数量的字符python改变的字符串列表

时间:2018-04-06 17:56:34

标签: python string

循环字符串并生成所有字符串列表的最佳方法是通过某些字符(例如[ACGT]乘以X(小于字符串长度的整数))与原始字符串不同。

例如字符串'AGT',其变化为2个字符:

"['AGCT']['AGCT']T", "A['AGCT']['AGCT']", "['AGCT']G['AGCT']"

现在我正在使用强制方法使用for循环来改变每个循环的1个字符。基本上我需要运行循环并创建一个新列表我想要的字符串更改量;例如,如果我想要2次更改,我需要运行循环2次,并且对于每个后续循环,我将使用前一循环中的列表。

sequences=['AGT','CGG']
l=[]
for sequence in sequences: 
    for i in range(len(sequence)):

        l.append( sequence[:i]+ 'C' +sequence[i+1:])
        l.append( sequence[:i]+ 'T' +sequence[i+1:])
        l.append( sequence[:i]+ 'G' +sequence[i+1:])
        l.append( sequence[:i]+ 'A' +sequence[i+1:])
new_lst=[]
for sequence in l: 
    for i in range(len(sequence)):

        new_lst.append( sequence[:i]+ 'C' +sequence[i+1:])
        new_lst.append( sequence[:i]+ 'T' +sequence[i+1:])
        new_lst.append( sequence[:i]+ 'G' +sequence[i+1:])
        new_lst.append( sequence[:i]+ 'A' +sequence[i+1:])

1 个答案:

答案 0 :(得分:0)

我假设你不关心插入删除字符,只关心替换。

据我所知,目前还没有有效的方法。这是一个指数问题。但itertools可以提供帮助。

s成为您变化的字符串(例如' AGT')。设variance为不同的字符数(例如2)。让alphabet成为允许字符列表(例如' ACGT')。

首先,您可以遍历所有可能随itertools.combinations(range(len(s)), r=variance)变化的索引组合。这会为您提供(0, 1)(0, 2)(1, 2)

接下来,您需要找出可以放在这些位置的所有替换字母组。您可以遍历与itertools.product(alphabet, repeat=variance)不同的字母。这会为您提供从字母表中生成的长度为variance的元组。

您可能希望确保用新字母替换字符串中的字母(例如,您不想将'AGT'中的前两个字母替换为'AG')。所以,你可能想检查一下。

以下代码将上述内容放在一起:

def replace(s, indices, replacement_letters):
    new_s = list(s)
    for (letter, idx) in zip(replacement_letters, indices):
        new_s[idx] = letter
    return ''.join(new_s)


def vary(s, variance, alphabet):
    # loop through the lists of positions that could differ in s
    for indices in itertools.combinations(range(len(s)), r=variance):
        # loop through lists of replacement letters for those positions
        for replacement_letters in \
                itertools.product(alphabet, repeat=variance):
            # check to make sure the replacement letters change s
            overlap = False
            for (letter, idx) in zip(replacement_letters, indices):
                if s[idx] == letter:
                    overlap = True
                    break
            if overlap:
                continue
            yield replace(s, indices, replacement_letters)


print(' '.join(vary('AGT', 2, 'GCAT')))
# GCT GAT GTT CCT CAT CTT TCT TAT TTT GGG GGC GGA CGG CGC CGA TGG TGC TGA ACG ACC ACA AAG AAC AAA ATG ATC ATA

潜在的改进:我非常确定你可以使用不同的itertools方法去除额外的检查步骤,以确保替换字母实际上都改变了字符串。无论如何,我希望这可以作为迭代工具方法的一个很好的演示,可以帮助像这样的指数爆炸案例。