我们有一个列表的列表,每个列表包含四个元素,分别是 id、age、val1 和 val2。我们正在以这样的方式操作每个列表,使得列表中 val1 和 val2 的值总是依赖于在先前的列表中看到的最新值。对于一个列表来说,先前的列表是指那些年龄差不小于 timeDelta 的列表。列表的列表按年龄排序。
我们的代码运行正常,但速度很慢。我们认为标记为 ** 的行会生成过多的列表的列表,可以通过在知道下一个列表的年龄差超过 timeDelta 时从开头删除列表来避免 **。
myList = [
[1, 20, '', 'x'],
[1, 25, 's', ''],
[1, 26, '', 'e'],
[1, 30, 'd', 's'],
[1, 50, 'd', 'd'],
[1, 52, 'f', 'g']
]
age_Idx =1
timeDelta = 10
for i in range(len(myList))[1:]:
newList = myList[:i+1] #Subset of lists. #********
respList = newList.pop(-1)
currage = float(respList[age_Idx])
retval = collapseListTogether(newList, age_Idx, currage, timeDelta)
if(len(retval) == 0):
continue
retval[0:2] = respList[0:2]
print(retval)
-
解决方案
为了解决这个问题,我们可以使用以下优化方法:
myList = [ [1, 20, '', 'x'], [1, 25, 's', ''], [1, 26, '', 'e'], [1, 30, 'd', 's'], [1, 50, 'd', 'd'], [1, 52, 'f', 'g'] ]age_Idx =1 timeDelta = 10 index = 0 for i in range(len(myList)): newList = myList[index:i+1] respList = newList.pop(-1) currage = float(respList[age_Idx]) retval = collapseListTogether(newList, age_Idx, currage, timeDelta) if(len(retval) == 0): continue retval[0:2] = respList[0:2] index = i print(retval)在这个优化的代码中,我们使用一个 index 变量来跟踪我们正在处理的当前列表的索引。在每个迭代中,我们使用 newList 变量创建一个新列表,其中包含从 index 到当前迭代的 i 索引的所有列表。这确保了我们只创建必要的列表的列表,从而减少了内存的使用和计算时间。
经过优化后,代码的运行速度有了明显的提高。
def collapseListTogether(li, age_Idx, currage, timeDelta):
finalList = []
for xl in reversed(li) :
#print(xl)
oldage = float(xl[age_Idx])
if ((currage-timeDelta) <= oldage < currage):
finalList.append(xl)
else:
break
return([reduce(lambda a, b: b or a, tup) for tup in zip(*finalList[::-1])])
这个 collapseListTogether 函数的功能是将一个列表的列表合并成一个列表,并将列表中的值按年龄排序。该函数使用 zip 和 reduce 函数来实现合并操作。
例子:
[1, 20, '', 'x'] ==> Not dependent on anything. Skip this list
[1, 25, 's', ''] == > [1, 25, '', 'x']
[1, 26, '', 'e'] ==> [1, 26, 's', 'x']
[1, 30, 'd', 's'] ==> [1, 30, 's', 'e']
[1, 50, 'd', 'd'] ==> Age difference (50-30 = 20) which is more than 10
[1, 52, 'f', 'g'] ==> [1, 52, 'd', 'd']