2013-05-18 63 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

相關問題