Python中for循环与while循环的效率

1 投票
1 回答
573 浏览
提问于 2025-04-18 12:57

我刚开始学习编程,选择了Python作为我的学习工具。目前我正在处理一些使用for循环和while循环的代码。

def missingDoor(trapdoor,roomwidth,roomheight,step):        
    safezone = []
    hazardflr = givenSteps(roomwidth,step,True)
    safetiles = []

    for i,m in enumerate(hazardflr):
    safetiles.append((m,step))
        while i < len(safetiles):
            nextSafe = safetiles[i]
            if knownSafe(roomwidth, roomheight, nextSafe[0], nextSafe[1]):
                if trapdoor[nextSafe[0]/roomwidth][nextSafe[0]%roomwidth] is "0":
                    if nextSafe[0] not in safezone:
                        safezone.append(nextSafe[0])
                    for e in givenSteps(roomwidth,nextSafe[0],True):
                        if knownSafe(roomwidth, roomheight, e, nextSafe[0]):
                            if trapdoor[e/roomwidth][e%roomwidth] is "0" and (e,nextSafe[0]) not in safetiles:
                                safetiles.append((e,nextSafe[0]))
            i += 1  
    return sorted(safezone)

后来在社区成员的帮助下,我把一个常用的变量nextSafe[0]设置为ns,这样就可以在代码的开头调用它,变得更高效了:

def missingDoor(trapdoor,roomwidth,roomheight,step):        
    safezone = []
    hazardflr = givenSteps(roomwidth,step,True)
    safetiles = []

    for i,m in enumerate(hazardflr):
    safetiles.append((m,step))
        while i < len(safetiles):
            nextSafe = safetiles[i]
            ns0 = nextSafe[0]
            if knownSafe(roomwidth, roomheight, ns0, nextSafe[1]):
                if trapdoor[ns0/roomwidth][ns0 % roomwidth] is "0":
                    if ns0 not in safezone:
                        safezone.append(ns0)
                    for e in givenSteps(roomwidth,ns0,True):
                        if knownSafe(roomwidth, roomheight, e, ns0):
                            if trapdoor[e/roomwidth][e%roomwidth] is "0" and (e, ns0) not in safetiles:
                                safetiles.append((e, ns0))
            i += 1  
    return sorted(safezone)

这些都提高了值的替换效率,但有没有其他方法可以让这个代码更高效,甚至节省一些行数?knownSafe()和givenSteps()这两个函数是从另一段代码中来的,它们和这段代码一起用来找出可能的安全区域和已知步骤。但我想问的只是如何让这段代码更高效,因为我最开始使用的是while循环,后来发现对于已知列表,for循环更好用。由于我还是编程新手,尝试了各种方法。

提前谢谢大家的帮助!!

1 个回答

1

所以……你想要代码审查吗?这里……

无论如何,我会尽量帮你……

代码

def missingDoor(trapdoor, roomwidth, roomheight, step):
    safezone, safetiles = [], []
    check = lambda a, b, c, l: knownSafe(roomwidth, roomheight, a, b) and trapdoor[a/roomwidth][a%roomwidth] == '0' and c not in l

    for i, m in enumerate(givenSteps(roomwidth, step, True)):
        safetiles.append((m, step))
        for _ in range(i, len(safetiles)):
            nextSafe = safetiles[i]
            ns0 = nextSafe[0]

            if check(ns0, nextSafe[1], ns0, safezone):
                safezone.append(ns0)
                safetiles.extend([ (e, ns0) for e in givenSteps(roomwidth,ns0,True) if check(e, ns0, (e, ns0), safetiles) ])
    return sorted(safezone)

解释

第1行:定义一个函数
第2行:声明变量,这种在一行中声明多个变量的方式并不是为了提高效率,而只是风格问题
第3行:这是一个重要的方法,因为它展示了函数式编程 (这是Python支持的一种编程范式)如何帮助代码更清晰(再次强调,这不是内存效率的问题,而是代码效率,这在长远来看会有帮助)……简单来说,lambda就是一个简化的函数,只包含一行代码,并返回结果,所以这里不需要return语句。实际上,lambda还有更多内容,但基本上就是在这种情况下你想要使用它的原因……这里的目标是检查变量,使用你每隔几行就运行的重复检查,我注意到这段代码有点乱!所以这个函数的存在就是为了简单地整理一下……前两个参数是显而易见的,第三个参数是要检查它是否存在于第四个参数中(我猜是一个列表)……
第5行:循环开始,没什么奇怪的,除了我直接在循环中使用了函数的返回值,因为我觉得把它存储为一个变量只用一次会浪费内存……
第6行:保持不变……
第7行:我把while循环改成了for循环,因为我注意到你使用while循环的唯一原因是外层循环每次运行时i的值会改变,所以,为什么不提供一个范围呢?这样会更节省代码和内存
第8、9行:保持不变……
第11行:我们使用了lambda,哇!和调用函数一样……
第12行:保持不变……
第13行:这里的技巧叫做列表推导,这有点高级,但简单来说,它创建了一个列表,每次内部循环运行时,都会将最左边的值添加到列表中,右边的任何条件在每次循环时都会执行,如果返回true,最左边的值就会被添加,否则,循环继续……从这些操作返回的列表,会被添加到safetiles列表中,注意:列表的extend方法会将参数列表中的所有元素添加到调用列表中,在这个例子中:列表推导的结果中的每个元素都会被添加到safetiles中……这看起来并不是多余的,因为它实际上使代码更清晰,并且使用了更少的内存……
第14行:返回safetiles列表…… 任务完成!

希望这对你有帮助;)请注意,使用“is '0'”来检查并不是一个好习惯,更好的方式是“== '0'”

撰写回答