优化两个简单的嵌套循环

优化嵌套循环的方法通常取决于具体的情况,但有几种常见的技巧可以尝试。尽可能减少内部循环的迭代次数,这可以通过更有效的算法或数据结构来实现。如果内部循环中使用的值在外部循环中已经计算过,可以尝试在外部循环中计算并将结果存储起来,避免重复计算。下面是一个简单的示例,演示了如何通过优化来减少嵌套循环的计算量:

在这里插入图片描述

1、问题背景

在优化以下两个嵌套循环时遇到了一些困难:

def startbars(query_name, commodity_name):

    global h_list
    nc, s, h_list = [], {}, {}
    query = """ SELECT wbcode, Year, """+query_name+""" 
                FROM innovotable WHERE commodity='"""+commodity_name+"""' and

                """+query_name+""" != 'NULL' """
    rows = cursor.execute(query)
    for row in rows:
        n = float(row[2])
        s[str(row[0])+str(row[1])] = n
        nc.append(n)
    for iso in result:
        try:
            for an_year in xrange(1961, 2031, 1):
                skey = iso+str(an_year)
                h_list[skey] = 8.0 / max(nc) * s[skey]
        except:
            pass

希望找到一些优化思路来提高代码效率。

2、解决方案

优化建议:

  1. 将内部循环从外部循环中分离出来。因为内部循环并不依赖于外部循环,因此可以将其提取出来,这将简化代码结构并提高效率。

  2. max(nc)移出循环。max(nc)在第一次循环后就是一个常量,因此可以将其移出循环以减少重复计算。

  3. 重新组织数据结构。优化后的代码使用了一个字典mapYearToWbcodeToField来存储数据,这使得查找更加高效。同时使用了一个列表nc来存储所有值的最大值,这样就可以在一次循环中计算出constant

以下是优化后的代码:

def startbars(query_name, commodity_name):

    assert query_name in INNOVOTABLE_FIELD_NAMES

    ## TODO: Replace with proper SQL query
    query = """ SELECT wbcode, Year, """+query_name+""" 
             FROM innovotable WHERE commodity='"""+commodity_name+"""' and

             """+query_name+""" != 'NULL' """
    rows = cursor.execute(query)

    mapYearToWbcodeToField = {}
    nc = []
    global h_list
    h_list = {}

    for row in rows:
        n = float(row[2])
        wbCodeToField = mapYearToWbcodeToField.setdefault(int(row[1]),{})
        wbCodeToField[str(row[0])] = n
        nc.append(n)

    constant = 8.0 / max(nc)


    for (an_year,wbCodeToField) in mapYearToWbcodeToField.iteritems():
        if an_year < 1961 or an_year > 2031:
            continue

        for (wbCode,value) in wbCodeToField.iteritems():
            if wbCode not in result:
                continue

            skey = wbCode+str(an_year)
            h_list[skey] = constant * value

或者,还可以将所有的检查都移到第一个循环中:

def startbars(query_name, commodity_name):

    assert query_name in INNOVOTABLE_FIELD_NAMES

    ## TODO: Replace with proper SQL query
    query = """ SELECT wbcode, Year, """+query_name+""" 
             FROM innovotable WHERE commodity='"""+commodity_name+"""' and

             """+query_name+""" != 'NULL' """
    rows = cursor.execute(query)

    data = []
    maxField = None

    for row in rows:
        an_year = int(row[1])
        if an_year < 1961 or an_year > 2031:
            continue

        wbCode = str(row[0])
        if wbCode not in result:
            continue

        n = float(row[2])

        data.append((wbCode+str(an_year),n))
        if maxField is None or n > maxField:
            maxField = n

    constant = 8.0 / maxField

    global h_list
    h_list = {}

    for (skey,n) in data:
        h_list[skey] = constant * n

在这个示例中,原始的嵌套循环遍历了二维数组中的所有元素,并将每个元素乘以2后添加到结果列表中。优化后的版本避免了使用range(len(data))range(len(data[i]))来遍历索引,而是直接遍历了二维数组中的每个元素。这种优化减少了重复计算,并使代码更简洁易读。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值