您的位置:首页 > 编程语言 > Python开发

踩的python列表及for循环一个坑儿

2016-06-13 09:27 387 查看
一个列表循环的问题,困扰了半个小时,我也是醉了,值得深思

下面开始提需求:

一个列表mylist = [{'tag':1,'num' :5000},{'tag':2,num: 6000},{'tag':3,num: 3000},{'tag':4,num: 1000} ],

列表的元素是字典,字典中有两个key,现在需要给定一个整数,比如说6000,用这个6000来消除列表里的字典元素,比较的对象就是字典里的num值,如果num小于6000,则直接删除该字典元素,然后6000减少num的值,接着继续往后比较,如果后面这个整数小于num的话,就让num减去这个整数值。最终的结果是让原来的列表经过比较之后,使用num值消除6000这个数

下面开始贴代码:

#!/usr/bin/env python

mylist = [{'tag':1,'num' :5000},{'tag':2,"num": 6000},{'tag':3,"num": 3000},{'tag':4,"num": 1000} ]
print mylist   #先打印一下列表,便于比较
res = 12000
for i in mylist:
if res == 0:      #首先判断res是否为0,。为0 的话表示这个整数已被减没了,后面的元素不再处理
continue
elif res >= i['num']:     #如果res大于num的时候,直接删除这个字典元素,然后res减去对应的值
res -= i['num']
mylist.remove(i)
continue
elif res < i['num']:  #如果res小于num的时候,num直接减去res的值,然后res置0
i['num'] -= res
res = 0
print mylist


当时我是根据这个逻辑来写的代码,执行结果如下:

原列表:[{'tag': 1, 'num': 5000}, {'tag': 2, 'num': 6000}, {'tag': 3, 'num': 3000}, {'tag': 4, 'num': 1000}]
处理后的列表:[{'tag': 2, 'num': 6000}, {'tag': 4, 'num': 1000}]


结果完全出人意料,tag2怎么没减呢,此时的res为12000,按道理说应该会吧tag1,tag2消除了,tag3的num值为2000,现在tag1消除是正常的,tag3怎么会消除呢,更神奇的是tag2竟然没减

下面对代码分步打print,看看问题出在哪

for i in mylist:
if res == 0:
print 1,i    #加print 1看看是否进入这个判断
continue
elif res >= i['num']:
print 2,i     #加print2  看看是否进入这个判断
res -= i['num']
mylist.remove(i)
continue
elif res < i['num']:
print 3,i    #加print3 看看是否进入这个判断
i['num'] -= res
res = 0


执行结果:

原列表:[{'tag': 1, 'num': 5000}, {'tag': 2, 'num': 6000}, {'tag': 3, 'num': 3000}, {'tag': 4, 'num': 1000}]

print的结果:2 {'tag': 1, 'num': 5000}
print的结果:2 {'tag': 3, 'num': 3000}

结果:[{'tag': 2, 'num': 6000}, {'tag': 4, 'num': 1000}]


发现只有tag1和tag3进入了循环,tag2和tag4呢?

接着继续打print

for i in mylist:
print i,mylist.index(i)   #打印一下元素的下标
if res == 0:
print 1,i
continue
elif res >= i['num']:
print 2,i
res -= i['num']
mylist.remove(i)
continue
elif res < i['num']:
print 3,i
i['num'] -= res
res = 0


执行结果:

原列表:[{'tag': 1, 'num': 5000}, {'tag': 2, 'num': 6000}, {'tag': 3, 'num': 3000}, {'tag': 4, 'num': 1000}]

{'tag': 1, 'num': 5000} 0
2 {'tag': 1, 'num': 5000}
{'tag': 3, 'num': 3000} 1
2 {'tag': 3, 'num': 3000}

结果:[{'tag': 2, 'num': 6000}, {'tag': 4, 'num': 1000}]


从打印结果中发现,tag1的下标索引为0,是正常的,tag3的下标按理说应该是2,怎么是1呢?

突然恍然大悟,for循环迭代列表的时候,是按照列表的下标索引来进行迭代,第一次循环下标0,拿到tag1,进行判断处理,符合res>num那个条件,所以执行了remove操作,res同时也减去了num 变为7000,此时列表已变成mylist=[{'tag': 2, 'num': 6000}, {'tag': 3, 'num': 3000}, {'tag': 4, 'num': 1000}],for循环开始第二次循环下标为1,,此时mylist[1]是{'tag': 3, 'num': 3000},所以会处理tag3,发现res>num,所以同样执行remove操作,把列表变成mylist=[{'tag': 2, 'num': 6000}, {'tag': 4, 'num': 1000}] ,继续循环下标2,发现mylist列表中没有了下面2的元素,所以就中止了循环,导致最终的结果为[{'tag': 2, 'num': 6000}, {'tag': 4, 'num': 1000}]

知道原因之后,改变一下思路,用新的列表来存储res < num,并且减去res后的元素,还有res=0之后的所有元素。最后将新列表的值复制给原来列表,就可以达到需求

mylist = [{'tag':1,'num' :5000},{'tag':2,"num": 6000},{'tag':3,"num": 3000},{'tag':4,"num": 1000} ]
print mylist
res = 12000
new_list= []
new_list= []
for i in mylist:
if res == 0:
new_list.append(i)
elif res > i['num']:
res -= i['num']
elif res < i['num']:
i['num'] -= res
res = 0
new_list.append(i)
mylist = new_list
print mylist


最终结果:

原列表:[{'tag': 1, 'num': 5000}, {'tag': 2, 'num': 6000}, {'tag': 3, 'num': 3000}, {'tag': 4, 'num': 1000}]
结果:[{'tag': 3, 'num': 2000}, {'tag': 4, 'num': 1000}]


完事儿!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: