使用多个for循环优化Python脚本

时间:2015-10-26 00:44:53

标签: python performance list optimization

我是python的超级新手,也是尝试优化脚本速度的超级新手。我有这个问题,我一直在教自己如何编写代码,这里是:

我有一个包含产品清单,价值和成本的数据集。有三种不同类型的产品(A,B,C) - 每种产品类型有30-100种产品。每种产品都有价值和成本。我必须从产品类型A中选择1个产品,从产品类型B中选择2个产品,从产品类型C中选择3个产品 - 一旦我使用产品,我就不能再次使用它(无需更换)。

我的目标是根据预算约束优化产品价值。

鉴于我基本上是在尝试创建一个组合列表,我从那里开始写了一些“for循环”以实现这一点。我最初试图在循环中做太多,并将数据类型更改为列表,因为从我的研究中听起来它会加速它 - 它确实加快了它的速度。

问题是我仍然只能处理350k记录,如果我在list_a中有30个项目,list_b中有50个项目,list_c中有50个项目,那么我需要大约7个小时才能完成。

我创建了3个列表列表 - (list_a,list_b和list_c),每个列表看起来都像下面的list_a示例。然后,我评估for循环内的每个排列,看看这个排列是否具有比当前最高值排列更高的值,并且成本是否低于约束。如果它满足这些条件,我将其附加到排列的主列表(combo_list)。

    list_a = [['product1','product1_cost','product1_value'],['product2','product2_cost','product2_value'],...]

    num_a = len(list_a)
    num_b = len(list_b)
    num_c = len(list_c)

    combo_list = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]] # this is to create the list of lists that I will populate

    a = 0 #for row numbers
    b1 = 0 
    c1 = 0 
    l = 0 #of iterations
    max_value = 0

    for a in range(0,num_a):
      for b1 in range(0,num_b):
        b2 = b1 + 1 #second b
          for b2 in range(b2,num_b):
            for c1 in range(0,num_c):
              c2 = c1 +1 #second c
                for c2 in range(c2,num_C):
                  c3 =c2+1 #third c
                  for c3 in range(c3,num_C):
                    data = [list_a[a][0],list_a[a][1],list_a[a][2],list_b[b1][0],list_b[b1][1],list_b[b1][2],list_b[b2][0],list_b[b2][1],list_b[b2][2],list_c[c1][0],list_c[c1][1],list_c[c1][2],list_c[c2][0],list_c[c2][1],list_c[c2][2],list_c[c3][0],list_c[c3][1],list_c[c3][2]]
                    total_cost = data[1] + data[4] + data[7] + data[10] + data[13] + data[16]
                    total_value = data[2] + data[5] + data[8] + data[11] + data[14] + data[17]
                    data[18]=total_cost
                    data[19]=total_value
                    if total_value >= max_value and total_cost <= constraint:
                      combo_list.append(data)
                      max_value = total_value
                    c3 +=1
                l +=1
                c2 +=1
            c1 +=1
        b2+=1
    b1 +=1
a +=1

然后我把它变成数据帧或csv

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

所以,我能够使用itertools组合来解决这个问题:

tup_b =  itertools.combinations(list_b, 2)
list_b = map(list,tup_b)
df_b = pd.DataFrame(list_b)

#Extending the list
df_b['B'] = df_b[0] + df_b[1] 
df_b = df_b[['B']]

#flatten list
b = df_b.values.tolist()
b = list(itertools.chain(*r))

# adding values and costs
r = len(b)
x=0
for x in range(0,r):
    cost = [b[x][1] +b[x][4]]
    value = [b[x][2] +b[x][5]]
    r[x] = r[x] +cost +value
    x +=1

#shortening list
df_b = pd.DataFrame(b)
df_b = df_b[[0,3,6,7]]
df_b.columns = ['B1','B2','cost','value']

然后,我对list_c做了同样的结构,结构如上,使用:

tup_c =  itertools.combinations(list_c, 3)

使用此时间从约5小时到8分钟处理......

感谢大家的帮助。