我有以下Python2.7代码:
listOfLists = []
for l1_index, l1 in enumerate(L1):
list = []
for l2 in L2:
for l3_index,l3 in enumerate(L3):
if (L4[l2-1] == l3):
value = L5[l2-1] * l1[l3_index]
list.append(value)
break
listOfLists.append(list)
L1、L2、L3、L4、L5列表为:
L1 = [[0.60, 0.95, 0.38, 1.02, 0.29, 0.43], [0.40, 0.09, 0.87, 0.85, 0.70, 0.46], [0.67, 0.91, 0.66, 0.79, 0.86, 0.06], [0.59, 1.81, 0.05, 1.88, 0.20, 0.48], [0.64, 0.34, 0.37, 1.39, 0.56, 0.27], [0.56, 0.34, 0.68, 2.79, 0.18, 0.42], [0.42, 1.67, 0.04, 0.44, 0.25, 0.94], [0.32, 1.92, 0.95, 2.85, 0.95, 0.96], [0.50, 0.68, 0.84, 1.79, 0.35, 0.09], [0.34, 0.66, 0.85, 0.35, 0.38, 0.59], [0.50, 0.79, 0.45, 2.93, 0.50, 0.92], [0.11, 0.11, 0.93, 1.11, 0.81, 0.49]] # a list of 12 sublists
L2 = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
L3 = [480, 120, 35, 0, 520, 300]
L4 = [120, 120, 120, 0, 300, 35, 35, 520, 300, 480, 120, 480, 0, 35, 0, 0, 300]
L5 = [5.4, 2.83, 1.16, 6.9, 0.76, 2.15, 5.61, 3.12, 1.57, 0.08, 5.36, 0.2, 1.2, 1.4, 2.9, 2.1, 3.5]
这些只是例子;实际上,这些列表包含数十万个数字。解释器需要几十秒来计算三个嵌套的for
循环。
是否有可能以某种方式加速此代码,例如使用itertools
或任何其他模块/函数?
编辑:我不能使用非标准的Python2.7模块(numpy,scipy…)
@Rogalski是对的,你肯定需要重新考虑算法(至少尝试一下)。
但是如果你找不到更好的算法,我想你可以在使用嵌套循环的同时通过一些技巧来加快速度。注意,我将把L*列表当作一些全局变量,不需要传递给每个函数。因此,您需要保持这些列表对新函数可见,或者将它们作为参数添加。
首先,试着清理一下。例如,您似乎从未使用过l1_索引,因此可以将其删除。然后可以将第一个循环中发生的所有事情移到函数中。然后它将如下所示:
这很好,但是理解比用appends循环更快(here您可以找到一篇关于这个主题的好文章)。第一个循环非常简单,所以让我们将它折叠成
listOfLists = [create_list(l1) for l1 in L1]
。我们可以对create_list函数执行相同的内环提取现在它看起来更有可读性,而且应该工作得更快一些。您也可以尝试使用内置的list函数在list(
l3_index = l3.index(L4[element-1])
,)中查找元素,但我不知道它是否会更快。请注意,lambda不会比通常的函数更快地以相同的方式执行相同的操作。但它们会破坏堆栈跟踪,从而使代码更难调试。从itertools开始,您可以使用组合,但随后您将需要预生成列表,因为没有按顺序向您提供组合的合同。你不需要拉链。
代码的一个问题是在嵌套循环的每一轮中循环遍历L3。解决这个问题的办法是增加一些预计算。您需要知道L4的每个元素对应的索引L3。你可以这样做:
既然你说了
the readability is not important as long as it speeds up the code
,这就是你的诀窍:这个代码比for循环快25%。但相信我,我会开枪打死任何在我的代码中写下这个的人。
下面的代码是@spacegoing和@Alissa的组合,结果最快:
谢谢你的耐心和时间。
相关问题 更多 >
编程相关推荐