3 回答

TA貢獻1921條經驗 獲得超9個贊
根據您要執行的操作,您可以使用該itertools模塊來最大程度地減少for循環(或zip)。在這種情況下,itertools.product將創建您使用4個循環完成的工作:
>>> list(product(range(3),repeat=4))
[(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 1, 0), (0, 0, 1, 1),
(0, 0, 1, 2), (0, 0, 2, 0), (0, 0, 2, 1), (0, 0, 2, 2), (0, 1, 0, 0),
(0, 1, 0, 1), (0, 1, 0, 2), (0, 1, 1, 0), (0, 1, 1, 1), (0, 1, 1, 2),
(0, 1, 2, 0), (0, 1, 2, 1), (0, 1, 2, 2), (0, 2, 0, 0), (0, 2, 0, 1),
(0, 2, 0, 2), (0, 2, 1, 0), (0, 2, 1, 1), (0, 2, 1, 2), (0, 2, 2, 0),
(0, 2, 2, 1), (0, 2, 2, 2), (1, 0, 0, 0), (1, 0, 0, 1), (1, 0, 0, 2),
(1, 0, 1, 0), (1, 0, 1, 1), (1, 0, 1, 2), (1, 0, 2, 0), (1, 0, 2, 1),
(1, 0, 2, 2), (1, 1, 0, 0), (1, 1, 0, 1), (1, 1, 0, 2), (1, 1, 1, 0),
(1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 2, 0), (1, 1, 2, 1), (1, 1, 2, 2),
(1, 2, 0, 0), (1, 2, 0, 1), (1, 2, 0, 2), (1, 2, 1, 0), (1, 2, 1, 1),
(1, 2, 1, 2), (1, 2, 2, 0), (1, 2, 2, 1), (1, 2, 2, 2), (2, 0, 0, 0),
(2, 0, 0, 1), (2, 0, 0, 2), (2, 0, 1, 0), (2, 0, 1, 1), (2, 0, 1, 2),
(2, 0, 2, 0), (2, 0, 2, 1), (2, 0, 2, 2), (2, 1, 0, 0), (2, 1, 0, 1),
(2, 1, 0, 2), (2, 1, 1, 0), (2, 1, 1, 1), (2, 1, 1, 2), (2, 1, 2, 0),
(2, 1, 2, 1), (2, 1, 2, 2), (2, 2, 0, 0), (2, 2, 0, 1), (2, 2, 0, 2),
(2, 2, 1, 0), (2, 2, 1, 1), (2, 2, 1, 2), (2, 2, 2, 0), (2, 2, 2, 1),
(2, 2, 2, 2)]
在您的代碼中,您可以執行以下操作:
for i,j,k,l in product(range(3),repeat=4):
#do stuff
此函數等效于以下代碼,不同之處在于實際實現不會在內存中建立中間結果:
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)
編輯:正如@ PeterE在評論中所說,product()即使范圍的長度不同,也可以使用:
product(range(3),range(4),['a','b','c'] ,some_other_iterable)

TA貢獻1864條經驗 獲得超6個贊
使用的想法itertools.product是一個好主意。這是一種更通用的方法,將支持各種大小的范圍。
from itertools import product
def product_of_ranges(*ns):
for t in product(*map(range, ns)):
yield t
for i, j, k in product_of_ranges(4, 2, 3):
# do stuff

TA貢獻1816條經驗 獲得超4個贊
它不會更加簡潔,因為它將花費您一個生成器函數,但是至少您不會被PEP8所困擾:
def tup4(n):
for i in range(n):
for j in range(n):
for k in range(n):
for l in range(n):
yield (i, j, k, l)
for (i, j, k, l) in tup4(3):
# do your stuff
(在python 2.x中,您應該使用xrange而不是range在generator函數中)
編輯:
當金字塔的深度已知時,上述方法應該很好。但是您也可以通過這種方式生成通用生成器,而無需任何外部模塊:
def tup(n, m):
""" Generate all different tuples of size n consisting of integers < m """
l = [ 0 for i in range(n)]
def step(i):
if i == n : raise StopIteration()
l[i] += 1
if l[i] == m:
l[i] = 0
step(i+ 1)
while True:
yield tuple(l)
step(0)
for (l, k, j, i) in tup(4, 3):
# do your stuff
(我用過,(l, k, j, i)因為在上面的生成器中,第一個索引首先變化)
添加回答
舉報