我正在编写一个应该输出列表A的所有k-way分区的函数。 这个问题显然是递归的,实现应该是直截了当的:
def gen_partition_k_group( A, k):
#
if len(A) == 0 :
# EDITED FOLLOWING SUGGESTION
yield [ [] for _ in xrange(k) ]
#
else :
# all k-partitions of the list of size N-1
for ss in gen_partition_k_group(A[:-1], k) :
assert( sum( len(gg) for gg in ss ) == len(A) -1 )
for ii in xrange(k) :
tt = list(ss)
print tt
tt[ ii ].append( A[ -1 ] )
print tt
assert( sum( len(gg) for gg in tt ) == len(A) )
yield tt
A = range(3)
k = 2
[ xx for xx in gen_partition_k_group( A, k) ]
输出
AssertionError:
[[],[]]
[[0],[0]]
我不明白输出。它应该是[[0], []]
而不是[[0], [0]]
。我错过了什么?
注意:我知道如何在没有append
的情况下编写不同的函数来输出正确的结果。 Iterator over all partitions into k groups?(第一个答案)
我不明白这个特定功能的行为。
答案 0 :(得分:1)
一个问题可能是[ [] ] * k
没有按照您的想法行事。这不会使k
为空列表,它会创建一个新的空列表,并k
引用它。例如:
>>> [[]]*3
[[], [], []]
>>> a = [[]]*3
>>> a
[[], [], []]
>>> a[0].append(1)
>>> a
[[1], [1], [1]]
>>> id(a[0]), id(a[1]), id(a[2])
(25245744, 25245744, 25245744)
>>> a[0] is a[1]
True
>>> a[0] is a[2]
True
要制作多个新列表,您可以执行类似
的操作>>> a = [[] for _ in xrange(3)]
>>> a
[[], [], []]
>>> id(a[0]), id(a[1]), id(a[2])
(41563560, 41564064, 41563056)
我认为这本身不会修复你的程序 - 我仍然会得到assert
绊倒 - 但它应该会有所帮助。
答案 1 :(得分:0)
好的问题是行tt = list(ss)
只是列表的浅表副本。使用tt = copy.deepcopy(ss)
解决了问题。