这是我生成小点广场的程序的一部分。它应该将形式[['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,我现在知道了我想要的功能,但是我仍然想知道我的代码出了什么问题....
答案 0 :(得分: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')]
答案 1 :(得分:1)
除了shang提供的最佳解决方案之外,您的代码中存在很多错误。其中一些是:
gamgam = gam[:]
for z in gam:
gamgam.append(z)
gam = gamgam[:]
我相信这是gam
列表的加倍,但是在行gamgam.append(z)
中,您要添加对同一子列表的另一个引用,因此结果将包含对初始子列表对的大量引用。 / p>
更新:这标记不是错误,因为gam
尺寸在周期中没有增加
if y < len(gam)/2:
当你将元素附加到gam时,len(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
<强> UPD:强>
根据要求,这是某种pythonic重新编码itertools.product
:
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))
也建议在这种情况下使用元组而不是列表。
答案 2 :(得分: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
的{{3}}。