我有一个元组列表,例如:
A=[(1,2,3), (3,5,7,9), (7)]
并希望使用每个元组中的一个项生成所有排列。
1,3,7
1,5,7
1,7,7
...
3,9,7
我可以拥有任意数量的元组,元组可以包含任意数量的元素。
我不能使用itertools.product()
,因为python 2.5。
答案 0 :(得分:13)
itertools.product
的文档有一个如何在py2.5中实现它的例子:
def product(*args, **kwds):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
pools = map(tuple, args) * kwds.get('repeat', 1)
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
答案 1 :(得分:5)
def product(*iterables):
""" Equivalent of itertools.product for versions < 2.6,
which does NOT build intermediate results.
Omitted 'repeat' option.
product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
"""
nIters = len(iterables)
lstLenths = []
lstRemaining = [1]
for i in xrange(nIters-1,-1,-1):
m = len(iterables[i])
lstLenths.insert(0, m)
lstRemaining.insert(0, m * lstRemaining[0])
nProducts = lstRemaining.pop(0)
for p in xrange(nProducts):
lstVals = []
for i in xrange(nIters):
j = p/lstRemaining[i]%lstLenths[i]
lstVals.append(iterables[i][j])
yield tuple(lstVals)
答案 2 :(得分:4)
itertools文档包含完整代码,显示每个函数的等价物。 product
实施是here。
答案 3 :(得分:3)
在使用生成器时,我也找到了itertools.product
的版本,它几乎与(本机)库版本一样快,同时与它100%兼容,并且它不会构建中间结果:
def product(*args, **kwds):
"Alternative fast implementation of product for python < 2.6"
def cycle(values, uplevel):
for prefix in uplevel: # cycle through all upper levels
for current in values: # restart iteration of current level
yield prefix + (current,)
stack = iter(((),))
for level in tuple(map(tuple, args)) * kwds.get('repeat', 1):
stack = cycle(level, stack) # build stack of iterators
return stack
使用python 2.7.3,我发现性能非常好(通常只有大约5-10倍,基本上相同的内存使用量)。
>>> import itertools as itt
>>> timeit for _ in itt.product(range(20), range(3), range(150)): pass
1000 loops, best of 3: 221 µs per loop
>>> timeit for _ in product(range(20), range(3), range(150)): pass
1000 loops, best of 3: 1.14 ms per loop
编辑:使代码更简单,Python 3就绪。