今天撸码时发现一个for循环的一个陷阱,调试了很久,现做下记录。
我的需求如下,有一个列表,假定该列表为tmp_list,该列表元素均为整数(包含正整数和负整数)。
我要从tmp_list的第一个元素开始依次取出20个元素求和,比如,tmp_list[0]到tmp_list[19]求和,tmp_list[1]到tmp_list[20]求和,tmp_list[2]到tmp_list[21]求和,以此类推。
代码如下(为说明问题简化后的代码):

def handle_list(tmp_list):
    tmp = []
    for i in num_list:
        # tmp追加一个值
        tmp.append(i)    
        if (num_list.index(i) >= 19):
            print("长度:%d" % len(tmp))
            # tmp弹出一个值
            pop_val = tmp.pop(0)

正常情况下,一旦tmp长度达到20的时候,以后将会一直保持20的长度(进一个,出一个),而实际情况呢,随着循环的继续,tmp的长度会随机的增长。
也就是说,在if语句块中的代码还没处理完的时候,tmp.append()可能执行了多次。
由于本人并不常用Python,对这个现象始终无法理解。
规避的措施,有以下两种,第一种如下:

def handle_list(tmp_list):
    tmp = []
    for i in num_list:
           # tmp追加一个值
        tmp.append(i)    
        if (len(tmp) >= 20):
            print("长度:%d" % len(tmp))
            # tmp弹出一个值
            pop_val = tmp.pop(0)

第二种:

def handle_list(tmp_list):
    tmp = []
    for i,val in enumerate(num_list):
           # tmp追加一个值
        tmp.append(val)    
        if (len(tmp) >= 20):
            print("长度:%d" % len(tmp))
            # tmp弹出一个值
            pop_val = tmp.pop(0)

后面两种方法,相比我的问题代码,可能更为科学。尤其第一种方法中的判断条件,相比最初的代码可能更为严谨。
由于一次丑陋的代码,发现了这个陷阱,以此文记之。

标签: Python

已有 2 条评论

  1. 爱哭的猫

    遇到同样的问题了,感谢大神总结。

  2. 暗黑王者

    苦李大神,膜拜!!

添加新评论