13

我可以得到这样的整数排列:

myInt = 123456789

l = itertools.permutations(str(myInt))
[int(''.join(x)) for x in l]

有没有更有效的方法在 Python 中获取整数排列,跳过创建字符串的开销,然后加入生成的元组?计时,元组连接过程使这比 list(l).

添加了支持信息

myInt =123456789
def v1(i): #timeit gives 258ms
    l = itertools.permutations(str(i))
    return [int(''.join(x)) for x in l]

def v2(i): #timeit gives 48ms
    l = itertools.permutations(str(i))
    return list(l)

def v3(i): #timeit gives 106 ms
    l = itertools.permutations(str(i))
    return [''.join(x) for x in l]
4

3 回答 3

5

你可以做:

>>> digits = [int(x) for x in str(123)]
>>> n_digits = len(digits)
>>> n_power = n_digits - 1
>>> permutations = itertools.permutations(digits)
>>> [sum(v * (10**(n_power - i)) for i, v in enumerate(item)) for item in permutations]
[123, 132, 213, 231, 312, 321]

这避免了与元组之间的转换,因为它将使用整数在元组中的位置来计算其值(例如,(1,2,3)means 100 + 20 + 3)。

因为 的值n_digits是已知的并且在整个过程中都是相同的,所以我认为您还可以优化计算以:

>>> values = [v * (10**(n_power - i)) for i, v in enumerate(itertools.repeat(1, n_digits))]
>>> values
[100, 10, 1]
>>> [sum(v * index for v, index in zip(item, values)) for item in permutations]
[123, 132, 213, 231, 312, 321]

我也认为我们不需要一直打电话zip(),因为我们不需要那个列表:

>>> positions = list(xrange(n_digits))
>>> [sum(item[x] * values[x] for x in positions) for item in permutations]
[123, 132, 213, 231, 312, 321]
于 2013-05-19T00:24:03.843 回答
0

这将为您提供一个生成器

import itertools as it
gen = it.permutations(range(1, 10))

然后您可以遍历每个项目:

for i in gen:
    #some code

或者将其转换为列表,但这需要一些时间:

items = list(gen)

编辑:澄清你想要一个整数,也许最快的方法是使用另一个惰性评估:

gen = (int('%d%d%d%d%d%d%d%d%d' % x) for x in it.permutations(range(1, 10)))
于 2013-05-19T00:13:10.587 回答
0

我无法评论 Simeon 的回答,所以我在这里添加。

如果您尝试120使用答案中的功能进行置换,您会得到

[120,102,210,201,12,21]

12 和 21 是错误的答案,所以我做了修改以丢弃它们:

def permute(n):
        digits = [int(x) for x in str(n)]
        n_digits = len(digits)
        n_power = n_digits - 1
        values = [v * (10**(n_power - i)) for i, v in
            enumerate(itertools.repeat(1, n_digits))]
        positions = list(range(n_digits))
        permutations = {sum(item[x] * values[x] for x in positions) for
            item in itertools.permutations(digits) if item[0] > 0}
        for p in permutations:
            yield p

编辑:还忘记添加该函数将对相同的数字进行两次计数,从而使您有重复项,因此我也对其进行了修改。

于 2018-12-18T00:58:40.303 回答