从两个字符串生成所有可能的字符串,保持在python中的位置

时间:2017-10-12 16:25:29

标签: python python-2.7 list itertools

有两个词:

AT
TC

我想生成所有可能的组合(不确定这里是否适用组合),可以通过替换这两个字符串的逐个字符来生成:

AT
TT
AC
TC

修改

我试过了:

from itertools import product
ref = "ACGT"
snp = "TGCA"
prod = product(ref,snp)
for p in prod:
    print p

但结果是:

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

不是我想要的。我期待类似的东西(每个结果应该与输入相同):

ACGT
TCGT
AGGT
ACGA
....

4 个答案:

答案 0 :(得分:3)

您正在寻找可能使用的itertools.product

>>> from itertools import product
>>> my_list = [ 'AT' , 'TC']

>>> list(product(*my_list))
[('A', 'T'), ('A', 'C'), ('T', 'T'), ('T', 'C')]

要将这些值作为字符串,您可以使用列表理解

>>> [''.join(s) for s in product(*my_list)]
['AT', 'AC', 'TT', 'TC']

修改(根据问题中的修改)

对于您分享的新示例,您应该将zip与上述列表理解表达式和itertools.product一起使用为:

>>> ref = "ACGT"
>>> snp = "TGCA"

>>> [''.join(s) for s in product(*zip(ref,snp))]
['ACGT', 'ACGA', 'ACCT', 'ACCA', 'AGGT', 'AGGA', 'AGCT', 'AGCA', 'TCGT', 'TCGA', 'TCCT', 'TCCA', 'TGGT', 'TGGA', 'TGCT', 'TGCA']

答案 1 :(得分:1)

这应该产生你想要的输出,其中两个字符串中的字符固定在它们的位置:

from itertools import product

ref = "ACGT"
snp = "TGCA"
for p in product(*zip(ref, snp)):
    ''.join(p)

'ACGT'
'ACGA'
'ACCT'
'ACCA'
'AGGT'
'AGGA'
'AGCT'
'AGCA'
'TCGT'
'TCGA'
'TCCT'
'TCCA'
'TGGT'
'TGGA'
'TGCT'
'TGCA'

zip这两个序列并迭代压缩对的笛卡尔积。

答案 2 :(得分:1)

以下内容应解决您的用例

list(''.join(s) for s in list(itertools.product(*zip(a, b))))

答案 3 :(得分:1)

考虑两个长度为四的字符串的情况。想象一下相同长度的一点掩码(四个)。每个可能的位掩码都应该对应于其中一个字符串的有效选择。

所以给出:

ABCD
zyxw

然后是结果:

0000 -> ABCD
0001 -> ABCw
0010 -> ABxD
0011 -> ABxw
0100 -> AyCD
0101 -> AyCw
0110 -> AyxD
0111 -> Ayxw

   .... and so on

概括地认为n字符串生成基数n中的所有数字,直到这些字符串长度的顺序。 (不确定你想如何处理非均匀的字符串长度;但原理是相同的,即使你添加某种“NULL”填充,它会从结果中滤除;类似于我们如何常规地从我们的前导零中过滤掉正常的十进制数表示。)

我现在没有时间为此编写代码。但方法是将这些字符串中的每一个映射到符号(数字或字符),并根据您的数字字符串及其长度迭代整数范围。例如,两个八个字符的字符串各为2 8(256),而三个七个字符的字符串各为3 7(2187),依此类推。

将每个整数转换为其在基础中的表示形式,并查找映射以从存储在该键的值(字符串)中提取该位置的字符。这与将整数转换为任何基数所使用的相同,取模数n并移位到零。