我需要创建列表中所有字符串的排列。我的列表可以长达300多个项目,因此我开始寻找从permutations
优化itertools
函数的方法。
不幸的是,列表的长度是必须的。缩小它是可能的,但就我的目的而言,列表越长越好。
我理解有多少排列是可能的,并且数字会根据排列长度呈指数级增长 - 这对我的目的也很重要。
到目前为止,我已经能够通过陪审团的方式只输出一定长度范围内的排列:
def bounded_permutations(iterable, min_length, max_length, outfilename, r=None):
outfile = open(outfilename,'w+')
outfile.truncate()
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n: return
indices = range(n)
cycles = range(n, n-r, -1)
if min_length <= len(str(''.join((tuple(pool[i] for i in indices[:r]))))) <= max_length:
outfile.writelines((str(''.join(tuple(pool[i] for i in indices[:r])))) + '\n')
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
if min_length <= len(str(''.join((tuple(pool[i] for i in indices[:r]))))) <= max_length:
outfile.writelines((str(''.join(tuple(pool[i] for i in indices[:r])))) + '\n')
break
else: return
这只是itertools库中的代码,插入了长度检查和outfile.write。我曾经输出到列表,因为我想按长度排序,但为了优化,我只是将它们写入文件,因此它们不会被存储。
我看到两个地方效率低下,但我还没能改善它:
在我看来,排列功能困扰着#39;生成所有行,但不返回不符合边界的行。我一直试图想出一种方法,甚至不会打扰。生成长度不合适的行。
条件检查包含元组的实际生成,因此如果元组有效,则需要生成两次元组。此外,长度检查需要执行len
,str
,join
和tuple
函数以及池中项目的完整迭代。这可能是最快的方式,但我还没有弄清楚如何在加入和转换之前确定完成的线的长度。
有什么想法吗?