2013-05-18 11 views
9

posso ottenere permutazioni interi in questo modo:Un modo più efficiente per ottenere permute intere?

myInt = 123456789 

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

C'è un modo più efficiente per ottenere interi permutazioni in Python, saltando il sovraccarico di creare una stringa, quindi unendo le tuple generate? A tempo, il processo di unione delle tuple rende questo 3x più lungo di list(l).

aggiunto informazioni di supporto

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

ho chiarito, più lungo di 'lista (l)' – jumbopap

+2

mi sono permesso di distacco alcuni risultati timeit per contribuire a chiarire il problema di OP –

risposta

0

Questo vi darà un generator:

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

Quindi è possibile iterare su ogni elemento:

for i in gen: 
    #some code 

o convertirlo in un elenco, ma ci vorrà del tempo:

items = list(gen) 

EDIT: Chiarito che si desidera indietro un intero, forse il modo più veloce sta usando un'altra valutazione pigra:

gen = (int('%d%d%d%d%d%d%d%d%d' % x) for x in it.permutations(range(1, 10))) 
+0

stavo per dire la stessa cosa, ma il suo codice è davvero molto più lento della lista chiamate –

+0

In questo processo non dovrei scorrere tutte le interi del generatore, convertire i numeri interi in una stringa, quindi ripetere di nuovo l'iterazione per unire ogni tupla, quindi convertire la tupla unita in pollici? – jumbopap

5

si può fare:

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

questo modo si evita la conversione da e verso un tupla poichè utilizzerà la posizione dell'intero nella tupla per calcolare il suo valore (ad esempio, (1,2,3) significa 100 + 20 + 3).

Poiché il valore di n_digits è noto e lo stesso in tutto il processo, penso che si può anche ottimizzare i calcoli per:

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

Penso anche che non abbiamo bisogno di chiamare zip() tutto il tempo perché non abbiamo bisogno di quella lista:

>>> 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

E la prima riga è uguale a 'digits = [int (x) per x in str (123)]' – Jared

+0

@Jared: grazie, ho aggiornato la risposta. –

+0

Funziona davvero, ma non credo che sia più efficiente della v1 di cui sopra. Grazie! – jumbopap

Problemi correlati