这对我有用。但是,它不会按顺序生成元素,而是先生成元素,然后对它们进行排序。
n = 5
i = np.array(np.indices(n * (2,))).reshape(n, -1)
i[:, np.argsort(i.sum(0)[::-1], kind='mergesort')].T[::-1]
它使用稳定的排序方式按数字的总和对二进制单词进行排序,即在出现平局的情况下保留原始顺序。
可以使用itertools构造按顺序生成单词的解决方案
itertools.chain((n*(0,),), (l[0] * (0,) + sum(((1,) + (i-j-1) * (0,) for i, j in zip(l[1:], l[:-1])), ()) + (1,) + (n-l[-1]-1)*(0,) for k in range(1,n+1) for l in itertools.combinations(range(n), k)))
这会循环 k 的数量(k = 0 是特殊情况并使用 itertools.chain 前置)。对于每个 k,它使用itertools.combinations 创建集合`{0, 1, ..., n-1} 并将每个子集转换为二进制字。这种翻译的工作原理是为 l 的每个元素放置一个 1,并计算中间必须有多少个零。前导零和尾随零必须是特殊情况。
示例输出:numpy:
# array([[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0],
[0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [1, 1, 0, 0, 0], [1, 0, 1, 0, 0],
[1, 0, 0, 1, 0], [1, 0, 0, 0, 1], [0, 1, 1, 0, 0], [0, 1, 0, 1, 0],
[0, 1, 0, 0, 1], [0, 0, 1, 1, 0], [0, 0, 1, 0, 1], [0, 0, 0, 1, 1],
[1, 1, 1, 0, 0], [1, 1, 0, 1, 0], [1, 1, 0, 0, 1], [1, 0, 1, 1, 0],
[1, 0, 1, 0, 1], [1, 0, 0, 1, 1], [0, 1, 1, 1, 0], [0, 1, 1, 0, 1],
[0, 1, 0, 1, 1], [0, 0, 1, 1, 1], [1, 1, 1, 1, 0], [1, 1, 1, 0, 1],
[1, 1, 0, 1, 1], [1, 0, 1, 1, 1], [0, 1, 1, 1, 1], [1, 1, 1, 1, 1]])
itertools:
list(_)
# [(0, 0, 0, 0, 0), (1, 0, 0, 0, 0), (0, 1, 0, 0, 0), (0, 0, 1, 0, 0), (0, 0, 0, 1, 0), (0, 0, 0, 0, 1),
(1, 1, 0, 0, 0), (1, 0, 1, 0, 0), (1, 0, 0, 1, 0), (1, 0, 0, 0, 1), (0, 1, 1, 0, 0), (0, 1, 0, 1, 0),
(0, 1, 0, 0, 1), (0, 0, 1, 1, 0), (0, 0, 1, 0, 1), (0, 0, 0, 1, 1), (1, 1, 1, 0, 0), (1, 1, 0, 1, 0),
(1, 1, 0, 0, 1), (1, 0, 1, 1, 0), (1, 0, 1, 0, 1), (1, 0, 0, 1, 1), (0, 1, 1, 1, 0), (0, 1, 1, 0, 1),
(0, 1, 0, 1, 1), (0, 0, 1, 1, 1), (1, 1, 1, 1, 0), (1, 1, 1, 0, 1), (1, 1, 0, 1, 1), (1, 0, 1, 1, 1),
(0, 1, 1, 1, 1), (1, 1, 1, 1, 1)]