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 に答える