1

我已经尝试寻找这个问题的答案,并阅读了很多关于装饰器和全局变量的内容,但没有找到任何与手头的问题完全合乎情理的东西:我想N使用A-alphabet,来制作 -length 的每一个排列fxn(A,N)。我将传递函数 2 个参数:AN. 它将产生长度的虚拟结果N。然后,使用N嵌套for循环,它将使用A从最内层循环开始的每个元素更新结果的每个索引。所以用fxn(‘01’,4)它会产生

1111, 1110, 1101, 1100, 1011, 1010, 1001, 1000, 
0111, 0110, 0101, 0100, 0011, 0010, 0001, 0000

如果您知道需要多少个嵌套循环(N; 虽然超过 4 个它开始变得非常混乱和麻烦),那么这样做很简单。但是,如果您想使用 A 制作所有任意长度的序列,那么您需要一些方法来自动化这种循环行为。特别是,我还希望此函数充当生成器,以防止必须将所有这些值存储在内存中,例如使用列表。要开始它需要初始化第一个循环,并使用单个值更改(要更新的索引)N-1次来继续初始化嵌套循环。然后它将产生最内层循环的值。

直接的方法fxn('01',4)是:

for i in alphabet:
    tempresult[0] = i
    for i in alphabet:
        tempresult[1] = i
        for i in alphabet:
            tempresult[2] = i
            for i in alphabet:
                tempresult[3] = i
                yield tempresult

基本上,我怎样才能将它扩展到任意长度的列表或字符串,并且仍然让每个嵌套循环更新适当的索引。我知道作为 numpy 的一部分可能有一个置换函数可以做到这一点,但我还没有遇到过。任何意见,将不胜感激。

4

2 回答 2

3

您实际上并不想要这里的排列,而是alphabet*alphabet*alphabet*alphabet. 你可以写成:

itertools.product(alphabet, repeat=4)

或者,如果你想取回字符串而不是元组:

map(''.join, itertools.product(alphabet, repeat=4))

(在 2.x 中,如果您希望它返回一个惰性迭代器而不是一个列表,就像您的原始代码一样,请使用itertools.imap而不是map。)


如果你想用 numpy 做到这一点,我能想到的最好的方法是使用一个递归函数,为每个因素平铺和重复,但这个答案有一个更好的实现,你可以从那里复制,或者显然退出scikit-learnas sklearn.utils.extmath.cartesian,然后这样做:

cartesian([alphabet]*4)

当然,这会给你一个 2D 的个位数字符串数组;您仍然需要多一步将其展平为 N 位字符串的一维数组,并且 numpy 会减慢您的速度,而不是加快产品计算的速度,所以……除非您确实需要一个 numpy 数组,否则我' d坚持itertools这里。

于 2013-10-07T21:36:39.580 回答
0

你可以看看这个itertools.permutations函数是如何工作的。

于 2013-10-07T21:35:21.507 回答