我能得到整数排列是这样的:
myInt = 123456789
l = itertools.permutations(str(myInt))
[int(''.join(x)) for x in l]
有没有一种更有效的方式来获得在Python 整数排列,跳过创建一个字符串,然后加入生成的元组的开销? 时序它的元组连接过程使得这个3倍长于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]
你可以做:
>>> 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]
这会给你一个发电机 :
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)))
我不能西面的回答发表评论,所以我在这里添加此。
如果您尝试置换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
编辑:还忘了补充一点,该函数将计算相同的数字的两倍,让你有重复,所以我修改了这一点。