我将为此使用python-builtin reduce,它似乎并不复杂,并且在我的测试中并没有那么慢:
from itertools import product
for x in product(range(3), range(2)):
rg = reduce(lambda result, index: result[index], x, lst)
value = rg[0]
如果您担心reduce带来的计时损失,则可以使用for循环代替:
for x in product(range(3), range(2)):
value = lst
for index in x:
value = value[index]
value = value[0]
在所有情况下,这将比手动索引慢,因为for循环将需要额外的操作来确定停止条件.与往常一样,问题在于,对于任意深度规范的灵活性,速度优化是否值得您这样做.
至于为什么要使用reduce vs. for,JavaScript社区内部一直在进行风格上的争论,即您应该在Arrays上使用reduce,map,filter函数还是使用for循环版本,因为它速度更快,并且您可能想参考那个辩论来选择你所处的立场.
for循环计时:
In [22]: stmt = '''
...: from itertools import product
...: def go():
...: lst = [[[1], [2]], [[3, 3], [4]], [[5], [6,6,6]]]
...: for x in product(range(3), range(2)):
...: # rg = reduce(lambda result, index: result[index], x, lst)
...: value = lst
...: for index in x:
...: value = value[index]
...: value = value[0]
...: # value = lst[x[0]][x[1]][0]
...: '''
In [23]: timeit(setup=stmt, stmt='go()', number=1000000)
Out[23]: 4.003296852111816
使用reduce的时间:
In [18]: stmt = '''
...: from itertools import product
...: def go():
...: lst = [[[1], [2]], [[3, 3], [4]], [[5], [6,6,6]]]
...: for x in product(range(3), range(2)):
...: rg = reduce(lambda result, index: result[index], x, lst)
...: value = rg[0]
...: # value = lst[x[0]][x[1]][0]
...: '''
In [19]: timeit(setup=stmt, stmt='go()', number=1000000)
Out[19]: 6.164631128311157
使用手动索引的时间:
In [16]: stmt = '''
...: from itertools import product
...: def go():
...: lst = [[[1], [2]], [[3, 3], [4]], [[5], [6,6,6]]]
...: for x in product(range(3), range(2)):
...: # rg = reduce(lambda result, index: result[index], x, lst)
...: value = lst[x[0]][x[1]][0]
...: '''
In [17]: timeit(setup=stmt, stmt='go()', number=1000000)
Out[17]: 3.633723020553589