我试图猜测两个巨大列表中两个数字的完美组合。
for x in list_a:
for y in list_b:
if round((x * 0.24 + y * 0.13), 2) == value:
print('success')
这花费了很多时间,因为我的列表的len超过600。我的第一个想法是将庞大的列表拆分为较小的列表并检查结果。例如,如果x和y的等式<=值-4移动到下一个列表的集合,直到x和y ==值。
1)如何将列表分成较小的集群? 2)如何有效地更改集? 3)有没有办法避免嵌套循环?
答案 0 :(得分:2)
我不太确定要尝试找到哪个最佳条件,但是如果您想在没有两个for循环的情况下重现以上计算,则可能会有所帮助。尝试计算一个numpy数组中的所有值:
arr = np.around(np.outer(0.24 * np.array(list_A), 0.13 * np.array(list_B)),2)
它将返回一个矩阵,该矩阵存储您正在for循环中计算的所有值,并且您可以获得一个布尔矩阵,该矩阵表明A和B的哪对满足条件
boolian_arr = arr == value
(此解决方案不包含任何奇特的搜索算法,只是使用numpy的两个慢速for循环的替代方法。)
答案 1 :(得分:2)
更新(澄清问题):
无需猜测,因为您可以精确求解(最多为数字):
M = np.array([[1, 1], [0.24, 0.13]])
high_taxed, low_taxed = np.linalg.solve(M, [Start_Value, Tax])
更新结束。
您可以使用以下技巧来获得O(n + m log n + m)运行时。
。
import numpy as np
def closest_match(a, b, v, fa=24, fb=13, fv=100):
ab = np.concatenate([fa*a, fv*v - fb*b])
idx = ab.argsort(kind='stable')
ina = idx<len(a)
swtch, = np.where(ina[1:]^ina[:-1])
mm = np.diff(ab[idx])[swtch]
abidx = swtch[np.argmin(np.abs(mm))]
aidx, bidx = sorted(idx[abidx:abidx+2])
bidx -= len(a)
return aidx, bidx
示例:
a = np.arange(-10, 10000, 7)
b = np.arange(20, 4000, 3)
v = 99
closest_match(a, b, v)
#(1, 249)
a[1]*24 + b[249]*13
#9899
v*100
#9900
# best match is one off
# validate using brute force
np.abs(np.add.outer(a*24, b*13)-v*100).min()
#1
# yep, one is as good as it gets
与蛮力相比的计时
timeit(lambda: np.unravel_index(np.abs(np.add.outer(a*24, b*13)-v*100).argmin(), (len(a), len(b))), number=1000)
#17.82432043197332
timeit(lambda: closest_match(a, b, v), number=1000)
#0.11731306000729091
提速超过100倍。