zoukankan      html  css  js  c++  java
  • 循环使用的一个坑

    不论使用什么编程语言,for和while循环基本都是通用的循环类型,而且我们也基本不会再用其它的循环控制结构了。

    我们知道,for一般针对一个次数固定的循环,而while则是判断是否满足条件再走循环。

    在很多情况下,用for和while都是可以实现需求的。当然了,在一般使用中,大家往往更偏爱for一些,因为循环变量可以不用自己操纵。

    但也许正因为如此,一些新手,比如以前的我,用着用着就真以为两者只是个语法形式不同而已了。而且前段时间又犯了一次错,证明了我还是很菜。

    今天我们来看看一个循环时容易踩的坑,借此来对比两者的不同。

    请看如下例子:

    对一个列表:

    >>> a=list(range(1,11))
    >>> a
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    现在要求:使用循环,去除其中的值小于5的项,即需要让它为[5,6,7,8,9,10]。

    看上去是个很简单的事情哈,可以这么写嘛:

    a=list(range(1,11))
    for i in a: if i<5: a.remove(i) print(a)

    查看运行结果:

    [2, 4, 5, 6, 7, 8, 9, 10]

    额...傻了。

    分析一下,在代码中加入一个计数变量看看:

    a=list(range(1,11))
    k=0
    for i in a:
        k+=1
        if i<5:
            a.remove(i)
    print(a)
    print(k)
    [2, 4, 5, 6, 7, 8, 9, 10]
    8

    原来这个“循环”竟然只走了8次...刚好是列表中2和4的那两次被漏掉了...

    这提示了我们想到,对列表的删除,改变了其索引序列,导致了遍历的遗漏。

    一栋房子,如果抽走了1楼,那上面的所有楼层的层级都要减1...

    但如果抽走的是顶楼,下面的所有楼层却不受影响~~~

    因此,如果使用反向循环,这个坑就不会踩了:([::-1]表示倒序)

    a=list(range(1,11))
    for i in a[::-1]:
        if i<5:
            a.remove(i)
    print(a)
    [5, 6, 7, 8, 9, 10]

    我们再来看看while,也是很容易出错的。首先我们要考虑到,如果while的判断条件是i<10,那就直接报错或死循环。因为列表a一被删除了项,长度就不再是10了,因此需要不断的重新计算列表a的长度。其次,还是刚才那个漏项的问题,一旦删除了某元素后,i的取值还得调整,否则是重蹈覆辙。

    a=list(range(1,11))
    i=0
    while i<len(a):
        if a[i]<5:
            a.remove(a[i])
            i=i-1
        i=i+1
    print(a)
    [5, 6, 7, 8, 9, 10]

    当然了,采用倒序遍历也是可以的。

    a=list(range(1,11))
    i=len(a)-1
    while i>=0:
        if a[i]<5:
            a.remove(a[i])
        i=i-1
    print(a)
    [5, 6, 7, 8, 9, 10]

    总结一下,示例问题的坑的本质是,循环条件依赖的变量随着循环的进行发生了改变,从而影响了循环的执行。

    对于一般的循环,确定次数的尽量用for,确定循环条件的尽量用while。(while的一个优势是每次循环都在重新检查条件,非常“仔细”)

    对于循环条件依赖的变量随着循环的进行可能发生改变的情况,最主要的还是要意识到这一点,至于具体用什么方法,都是灵活处理吧。

  • 相关阅读:
    CDN使用心得
    IIS6.0实现SSL安全加密
    从print css谈样式表的媒介(media)属性
    ASP.NET文件下载各种方式比较:对性能的影响、对大文件的支持、对断点续传和多线程下载的支持
    “同名Cookie”的分析
    周末部门游玩顺德碧桂园度假村
    Linux特殊文件权限
    周末部门游玩广州长隆欢乐世界
    开个博客
    iOS TableView数据绑定的原则
  • 原文地址:https://www.cnblogs.com/maoerbao/p/11864582.html
Copyright © 2011-2022 走看看