如何从一组字母中生成所有可能的模式?
How to generate all possible patterns from a set of letters?
如何使用 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']
实现它的一种方法是递归。这是执行此操作的生成器函数的示例:
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
如果使用递归的形式会容易很多。
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,简单 return 基础
如果 k > 1,找到 PatternGenerate(k-1) 并附加 base.
使用 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的非常相似
这是一种使用 repeat
和 product
来自 itertools
的方法:
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
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
,l2
和 l3
是 "iterables",例如列表或字符串。这适用于任何数字或可迭代对象:
零:
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
方法,我们在 "list comprehension"([]
之间)或 "generator expression"(()
之间)中使用该方法.
列表理解创建完整列表,而生成器表达式一个一个地生成元素,"on demand"。
如何使用 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']
实现它的一种方法是递归。这是执行此操作的生成器函数的示例:
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
如果使用递归的形式会容易很多。
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,简单 return 基础 如果 k > 1,找到 PatternGenerate(k-1) 并附加 base.
使用 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的非常相似
这是一种使用 repeat
和 product
来自 itertools
的方法:
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
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
,l2
和 l3
是 "iterables",例如列表或字符串。这适用于任何数字或可迭代对象:
零:
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
方法,我们在 "list comprehension"([]
之间)或 "generator expression"(()
之间)中使用该方法.
列表理解创建完整列表,而生成器表达式一个一个地生成元素,"on demand"。