2013-05-18 32 views
9

我能得到整数排列是这样的:更有效的方法来获得整数排列?

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] 
+0

我澄清,长于名单(L)' – jumbopap

+2

我花了一些发布timeit结果,以帮助澄清OP的问题的自由 –

回答

0

这会给你一个generator

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))) 
+0

我正要说同样的事情,但他的代码确实如此比调用列表慢得多 –

+0

在这个过程中,我不必遍历生成器中的每个整数,将整数转换为一个字符串,然后再次迭代以加入每个元组,然后将加入的元组转换回ints? – jumbopap

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)表示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] 
+0

第一行与'digits = [int(x)for str(123)]' – Jared

+0

@Jared:谢谢,我已经更新了答案。 –

+0

这确实有效,但我不认为它比上面给出的v1更有效。谢谢! – jumbopap

相关问题