问题描述
由于我的代码运行时间过长,我未能通过自动筛选考试的几个测试用例。有没有一种方法可以更有效地编写此代码?
提示类似于:
编写一个程序,该程序将列表作为输入,并返回成对连接其元素的所有组合的总和。
例如,列表[20,5]为:
2020 + 205 + 520 + 55 = 2800
我仍然想不出一种方法,而不必转换为字符串并返回int。列表理解以前是嵌套在循环中的,循环执行得较差,但是我仍然需要更高的速度。
def concatenationsSum(a):
# turn into strings
a = [str(i) for i in a]
# concat
cartesian_product = [j + k for j in a for k in a]
# turn back into integers
total = [int(i) for i in cartesian_product]
return sum(total)
解决方法
所以我尝试对您的代码进行一些优化,这里的主要瓶颈是强制转换为str并返回int,因此我修改了该部分
def concatenationsSum(a):
numDigits = {i: (10 ** (int(math.log10(i)) + 1)) for i in a}
cpro = product(a,a)
cartesian_product = [i * numDigits[x] + x for i,x in cpro]
return sum(cartesian_product)
在这里您可以看到我更改了几部分,我添加了一个字典以查找每个数字所需要乘以的位数,例如5将返回10,因此当您有20和5时,您可以{ 1}}可以加快整个过程的速度。
也不需要在列表理解中使用double for循环python itertools提供20 * digits[5] + 5 = 205
来返回笛卡尔积。
已完成测试:使用大约8个元素的小列表,我从4.6e05降低到3.1e05,使用5400个元素的较大列表,它从平均11.7秒提高到5.3秒。这大约是速度的两倍。