python for循环在每次循环时都会更新条件中的相关变量值

我去,困扰我小半个上午的问题终于悟到了。。。

得到两个很简单但平时不怎么注意到的结论:

  • for循环在每次循环时都会更新判断条件中的变量值,相当于每次判断的时候都会以变量最新值来判断是否满足循环条件,而不是一直保持初次进行判断时候的值。如for col in cols:如果循环体中改变了cols,那么下次循环时cols就按最新的来。
  • for col in cols:看着像是以cols中的元素值进行判断,其实使用的是索引,每次循环其实改变的是索引icol是以索引取出的值cols[i]。结合上一条容易发现如果在循环体中改变了cols,那结果显然会与预期不符。

上述描述可能还比较抽象,下面记录一下今天上午犯的小迷糊。
问题发生:
为了描述方便和问题呈现的直观性,我定义一个list来复现我遇到的问题。
我的目的是删除cols中包含[MAX]\[max]\[MIN]\[min]字符的元素。代码如下:

filterlist = ['[MAX]','[MIN]','[max]','[min]']
cols = ['WTUR_Temp_Ra_F32_TowerBase[MAX]', 'WGEN_Temp_Ra_F32_4[AVG]', 'WTPS_Temp_Ra_F32_Pcap3[MAX]', 'WTPS_Temp_Ra_F32_gen3[MIN]',
        'WGEN_Temp_Ra_F32_1[MAX]', 'WNAC_Temp_Ra_F32[MIN]', 'WYAW_CTim_Rt_F32_Ygen[min]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]']
for col in cols:
    for filt in filterlist:
        if filt in col:
            cols.remove(col)
print(cols)

出人意料的是,得到的结果竟然是这样的:

['WGEN_Temp_Ra_F32_4[AVG]', 'WTPS_Temp_Ra_F32_gen3[MIN]', 'WNAC_Temp_Ra_F32[MIN]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]']

问题寻解:
我真的百思不得其解。。因为这块代码逻辑很简单,就死活没想出来究竟哪里出问题了,但结果又是错的,于是就在能想到的可能出现的问题的地方print了一下,豁然开朗。。。
调试代码如下:

filterlist = ['[MAX]','[MIN]','[max]','[min]']
cols = ['WTUR_Temp_Ra_F32_TowerBase[MAX]', 'WGEN_Temp_Ra_F32_4[AVG]', 'WTPS_Temp_Ra_F32_Pcap3[MAX]', 'WTPS_Temp_Ra_F32_gen3[MIN]',
        'WGEN_Temp_Ra_F32_1[MAX]', 'WNAC_Temp_Ra_F32[MIN]', 'WYAW_CTim_Rt_F32_Ygen[min]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]']
i = 0
for col in cols:
    i += 1
    print(i,cols,col)
    for filt in filterlist:
        if filt in col:
            cols.remove(col)

打印结果:

1 ['WTUR_Temp_Ra_F32_TowerBase[MAX]', 'WGEN_Temp_Ra_F32_4[AVG]', 'WTPS_Temp_Ra_F32_Pcap3[MAX]', 'WTPS_Temp_Ra_F32_gen3[MIN]', 'WGEN_Temp_Ra_F32_1[MAX]', 'WNAC_Temp_Ra_F32[MIN]', 'WYAW_CTim_Rt_F32_Ygen[min]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]'] WTUR_Temp_Ra_F32_TowerBase[MAX]
2 ['WGEN_Temp_Ra_F32_4[AVG]', 'WTPS_Temp_Ra_F32_Pcap3[MAX]', 'WTPS_Temp_Ra_F32_gen3[MIN]', 'WGEN_Temp_Ra_F32_1[MAX]', 'WNAC_Temp_Ra_F32[MIN]', 'WYAW_CTim_Rt_F32_Ygen[min]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]'] WTPS_Temp_Ra_F32_Pcap3[MAX]
3 ['WGEN_Temp_Ra_F32_4[AVG]', 'WTPS_Temp_Ra_F32_gen3[MIN]', 'WGEN_Temp_Ra_F32_1[MAX]', 'WNAC_Temp_Ra_F32[MIN]', 'WYAW_CTim_Rt_F32_Ygen[min]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]'] WGEN_Temp_Ra_F32_1[MAX]
4 ['WGEN_Temp_Ra_F32_4[AVG]', 'WTPS_Temp_Ra_F32_gen3[MIN]', 'WNAC_Temp_Ra_F32[MIN]', 'WYAW_CTim_Rt_F32_Ygen[min]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]'] WYAW_CTim_Rt_F32_Ygen[min]

第一次打印的就是最开始的cols,这是没问题的,包括col也是cols中第一个元素。但是第二次起,问题就表现出来了,此时的cols已经是上一步移除了第一个元素后的cols,而for循环又是按照list的索引在取元素,这是第二次循环,因此要取此时cols中的第二个元素,于是'WGEN_Temp_Ra_F32_4[AVG]'就被跳过了。同样地,第三次for循环,取第三个元素,'WGEN_Temp_Ra_F32_4[AVG]','WTPS_Temp_Ra_F32_gen3[MIN]', 这两个就被跳过去了,后面同理。这样下来,很多元素被跳过了比较,结果自然就与我以为的有所偏差。找到病症,就好解决了。
两个思路:1.保证for循环时cols不变,只改变元素索引 2.可以改变cols,但是要保证每次都是拿当前cols中第一个元素进行比较。
我选择了第一种,最终实现了我预期功能的代码如下:

filterlist = ['[MAX]','[MIN]','[max]','[min]']
cols = ['WTUR_Temp_Ra_F32_TowerBase[MAX]', 'WGEN_Temp_Ra_F32_4[AVG]', 'WTPS_Temp_Ra_F32_Pcap3[MAX]', 'WTPS_Temp_Ra_F32_gen3[MIN]',
        'WGEN_Temp_Ra_F32_1[MAX]', 'WNAC_Temp_Ra_F32[MIN]', 'WYAW_CTim_Rt_F32_Ygen[min]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]']
drop = []
for col in cols:
    for filt in filterlist:
        if filt in col:
            drop.append(col) 
rem = list(set(cols)-set(drop))
print(rem)

输出:

['WGEN_Temp_Ra_F32_4[AVG]', 'WGEN_Spd_Ra_F32_overspblade1[AVG]']
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值