如何从一组字母生成所有可能的模式?

时间:2019-02-01 20:53:22

标签: python bioinformatics

如何使用k参数简化此函数中的for循环?

def PatternGenerate(k):
    base = ['A','C','G','T']
    pattern = []
    for x in base:
        for y in base:
            for z in base:
                result = str(x) + str(y) + str(z)
                pattern.append(result)
    return pattern

我得到了想要的结果,但没有得到函数:

  

['AAA','AAC','AAG','AAT','ACA','ACC','ACG','ACT','AGA','AGC','AGG','AGT ”,“ ATA”,“ ATC”,“ ATG”,“ ATT”,“ CAA”,“ CAC”,“ CAG”,“ CAT”,“ CCA”,“ CCC”,“ CCG”,“ CCT”, 'CGA','CGC','CGG','CGT','CTA','CTC','CTG','CTT','GAA','GAC','GAG','GAT','GCA ”,“ GCC”,“ GCG”,“ GCT”,“ GGA”,“ GGC”,“ GGG”,“ GGT”,“ GTA”,“ GTC”,“ GTG”,“ GTT”,“ TAA”, 'TAC','TAG','TAT','TCA','TCC','TCG','TCT','TGA','TGC','TGG','TGT','TTA','TTC ','TTG','TTT']

4 个答案:

答案 0 :(得分:1)

一种实现方法是递归。这是生成器函数执行此操作的示例:

def genAll(depth, base = ['A','C','G','T']):
    if depth <= 0:
        yield ''
    else:
        for char in base:
            for tail in genAll(depth - 1, base):
                yield char + tail

for comb in genAll(2):
    print(comb)

输出:

AA
AC
AG
AT
CA
CC
CG
CT
GA
GC
GG
GT
TA
TC
TG
TT

答案 1 :(得分:0)

如果您使用递归形式,将会容易得多。

def PatternGenerate(k):
    base = ['A','C','G','T']
    pattern = []
    if k == 1:
      return base
    else:
      for p in PatternGenerate(k-1):
        for b in base:
          pattern.append(p+b)

      return pattern

说明 这个想法是: 如果k == 1,则简单返回基数 如果k> 1,则找到PatternGenerate(k-1)并附加基数。

答案 2 :(得分:0)

使用itertools的Lazier版本

import itertools
k = 2
result = ["".join(t) for t in itertools.combinations_with_replacement(['A','C','G','T'], k)]
print(result)

combinations_with_replacement中的实现与@Andriy的实现非常相似。

答案 3 :(得分:0)

这是一种使用repeat中的productitertools的方法:

from itertools import product, repeat

# This one returns a list, like your version:
def list_all_kmers(k):
    return ["".join(nucls) for nucls in product(*repeat("ACGT", k))]

# This one generates k-mers one by one:
def generate_all_kmers(k):
    # It seems "return" also works
    # I'm not sure it makes a difference here
    # but see https://stackoverflow.com/a/45620965/1878788
    yield from ("".join(nucls) for nucls in product(*repeat("ACGT", k)))

for kmer in generate_all_kmers(3):
    print(kmer)

结果:

AAA
AAC
AAG
AAT
ACA
ACC
ACG
ACT
AGA
AGC
AGG
AGT
ATA
ATC
ATG
ATT
CAA
CAC
CAG
CAT
CCA
CCC
CCG
CCT
CGA
CGC
CGG
CGT
CTA
CTC
CTG
CTT
GAA
GAC
GAG
GAT
GCA
GCC
GCG
GCT
GGA
GGC
GGG
GGT
GTA
GTC
GTG
GTT
TAA
TAC
TAG
TAT
TCA
TCC
TCG
TCT
TGA
TGC
TGG
TGT
TTA
TTC
TTG
TTT

一些解释:

repeat("ACGT", k)生成k次"ACGT"。当从列表中列出时,可以将其可视化:

list(repeat("ACGT", 3))

结果:

['ACGT', 'ACGT', 'ACGT']

product(l1, l2, l3)生成所有元组,它们的第一个元素来自l1,第二个元素来自l2,第三个元素来自l3,其中l1,{{1} }和l2是“可迭代对象”,例如列表或字符串。这适用于任何数字或可迭代项:

零:

l3

结果:

list(product())

一个:

[()]

结果:

list(product("ACGT"))

两个:

[('A',), ('C',), ('G',), ('T',)]

结果:

list(product("ACGT", "ACGT"))

等等。

但是,如果要使用[('A', 'A'), ('A', 'C'), ('A', 'G'), ('A', 'T'), ('C', 'A'), ('C', 'C'), ('C', 'G'), ('C', 'T'), ('G', 'A'), ('G', 'C'), ('G', 'G'), ('G', 'T'), ('T', 'A'), ('T', 'C'), ('T', 'G'), ('T', 'T')] 的结果,则必须使用repeat来表示必须将生成的元素作为单独的参数。在函数调用中,*就像f(*[l1, l2, l3])。如果您使用生成器而不是列表,它也可以工作,因此我们不需要做f(l1, l2, l3)(我们只是出于可视化目的而在上面做了)。

然后,我们要使用元组中的元素制作字符串。这要归功于空字符串的list(repeat(...))方法,我们在“列表理解”(join之间)或“生成器表达式”([]之间)中使用了此方法。 / p>

列表理解会创建完整列表,而生成器表达式会“按需”逐个生成元素。