python迭代中的数字排列

时间:2015-08-12 09:38:30

标签: python permutation

我需要生成数字排列,数字可能大于数字计数。出于我目前的目的,我需要生成这些数字0, 1, 2的排列,以获得长达20位的数字。例如,我的前几个排列将是0, 1, 2, 10, 11, 12, ... 1122, 1211

在Python herehere中使用Iterator存在现有答案,这些答案直接提供了完整的排列。

但是我需要对每个排列执行一些测试,如果我将整个排列列表保留在内存中它会变得太大,特别是对于20个数字,它会达到3 20 排列。

所以我的问题是可以在没有递归的情况下完成,这样我就可以对每个排列执行测试。

修改

我正在重复查看排列。因此,对于多个说20个数字,每个数字可以从[0, 1, 2]获取值。这就是为什么在这种情况下排列的数量将达到3 20

3 个答案:

答案 0 :(得分:2)

是的,你的程序可能是这样的:

import itertools


def perform_test(permutation):
    pass

# permutations() does not construct entire list, but yields 
# results one by on.
for permutation in itertools.permutations([1, 2, 3, 4, 5], 2):
    perform_test(permutation)

答案 1 :(得分:2)

您所看到的被称为笛卡尔积,而不是置换。 Python itertools有一个方法itertools.product()来产生所需的结果:

import itertools

for p in itertools.product(range(3), repeat=4):
    print p

输出为3 ^ 4行:

(0, 0, 0, 0)
(0, 0, 0, 1)
(0, 0, 0, 2)
(0, 0, 1, 0)
(0, 0, 1, 1)
...
(2, 2, 2, 1)
(2, 2, 2, 2) 

要生成长度为1到4的输出元组,请使用额外的迭代:

for l in range(1, 5):
    for p in itertools.product(range(3), repeat=l):
        print p

最后,这也适用于字符串元素:

for i in range(5):
    for p in itertools.product(('0', '1', '2'), repeat=i):
        print ''.join(p),
print

输出:

0 1 2 00 01 02 10 11 12 20 21 22 000 001 002 010 [...] 2220 2221 2222

答案 2 :(得分:1)

虽然有很多方法可以使用itertools等来实现这一点,但这里的方法与您通常采用的方式略有不同。

如果您要按顺序列出这些排列,那么您实际拥有的是表示它们在列表中的位置的三元数。例如list [4]是11,其中三元组为4(3 * 1 + 1 * 1)。因此,您可以将要测试的索引值转换为三元,这将产生正确的值。

虽然python可以在整数中转换为整数到其形式(例如int(“11”,3)输出4),但反过来并未隐式实现。虽然有很多实现。 Here是一个很好的(根据您的情况进行了修改):

def digit_to_char(digit):
    if digit < 10:
        return str(digit)
    return chr(ord('a') + digit - 10)

def perm(number):
    (d, m) = divmod(number, 3)
    if d > 0:
        return perm(d) + digit_to_char(m)
    return digit_to_char(m)

因此,如果你想找到第20个排列,你可以做烫发(20),它会给你202.所以现在你可以只做一个你想要的索引值的常规循环。没有在内存中存储大的列表。

permutation = 0
i = 0
while len(str(permutation)) < 20:
    permutation = perm(i)
    do_test(permutation)
    i += 1