为什么这个庞奈特方格失败了?
这是我程序的一部分,用来生成杂交方格。它应该把一种形式为 [['A','a'],['b','b'],['C','C']...] 的“基因组”分离成可能的配子:
def gene_erator2(gen):
gam = [[], []]
q = 0
for x in gen:
q = q + 1
if q > 1:
gamgam = gam[:]
for z in gam:
gamgam.append(z)
gam = gamgam[:]
for y in range(len(gam)):
if y < len(gam)/2:
gam[y].append(x[0])
else:
gam[y].append(x[1])
return gam
当我执行
gene_erator2([['A','a'], ['B','b'], ['X','Y']])
时,我得到的是
[['A', 'B', 'b', 'X', 'X', 'Y', 'Y'], ['a', 'B', 'b', 'X', 'X', 'Y', 'Y'], ['A', 'B', 'b', 'X', 'X', 'Y', 'Y'], ['a', 'B', 'b', 'X', 'X', 'Y', 'Y'], ['A', 'B', 'b', 'X', 'X', 'Y', 'Y'], ['a', 'B', 'b', 'X', 'X', 'Y', 'Y'], ['A', 'B', 'b', 'X', 'X', 'Y', 'Y'], ['a', 'B', 'b', 'X', 'X', 'Y', 'Y']]
而不是我期待的
[['A', 'B', 'X'], ['a', 'B', 'X'], ['A', 'b', 'X'], ['a', 'b', 'X], ['A', 'B', 'Y'], ['a', 'B', 'Y'], ['A', 'b', 'Y'], ['a', 'b', 'Y']]
....这是什么?我说,这到底是什么?
编辑:现在我知道了一个能实现我想要功能的函数,感谢Shang,但我还是想知道我的代码出了什么问题....
3 个回答
1
除了shang提供的最佳解决方案外,你的代码中还有很多错误。以下是一些问题:
I
gamgam = gam[:]
for z in gam:
gamgam.append(z)
gam = gamgam[:]
我认为这里是对gam
列表的重复使用,但在gamgam.append(z)
这一行,你实际上是把同一个子列表的另一个引用添加进去了,所以结果会包含很多对最初子列表的引用。
II
更新:这并不是一个错误,因为在循环过程中gam
的大小并没有增加
if y < len(gam)/2:
在这种情况下,len(gam)
会随着你向gam
添加元素而增加,所以它不会像你想的那样工作。
所以尽管整个解决方案看起来不太美观,但只要修正这两个问题,这段代码就能正常工作:
def gene_erator2(gen):
gam = [[], []]
q = 0
for x in gen:
q = q + 1
if q > 1:
gamgam = gam[:]
for z in gam:
gamgam.append(z[:])
gam = gamgam[:]
lenGam = len(gam)
for y in range(lenGam):
if y < lenGam/2:
gam[y].append(x[0])
else:
gam[y].append(x[1])
return gam
更新:
根据要求,这是对itertools.product
的一种python风格的重写:
def product(collections):
if collections:
for subproduct in product(collections[1:]):
for element in collections[0]:
yield list(element) + subproduct
else: yield []
def gene_erator2(gen): return list(product(gen))
此外,在这种情况下,建议使用元组而不是列表。
1
还有一种解决这个问题的方法,不用 itertools.product
:
def gene_erator2(args):
result = [[]]
for pool in args:
result = [x+[y] for x in result for y in pool]
return result
另外,可以看看 itertools.product
的 文档。
4
标准库里有一个函数可以满足你的需求。
import itertools
def gene_erator2(gen):
return itertools.product(*gen)
这个函数会返回一个迭代器,迭代器可以让你遍历所有的组合。
>>> i = gene_erator2([['A','a'],['B','b'],['X','Y']])
>>> list(i)
[('A', 'B', 'X'), ('A', 'B', 'Y'), ('A', 'b', 'X'), ('A', 'b', 'Y'), ('a', 'B', 'X'), ('a', 'B', 'Y'), ('a', 'b', 'X'), ('a', 'b', 'Y')]