一个列表循环的问题,困扰了半个小时,我也是醉了,值得深思
下面开始提需求:
一个列表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}]

完事儿!!!

踩的python列表及for循环一个坑儿的更多相关文章

  1. python的默认参数的一个坑

    前言 pass 正文 在 https://docs.python.org/3/tutorial/controlflow.html#default-argument-values 中,有这样一段话 Im ...

  2. python 列表复制给另一个列表,改值两个列表均会改变(备忘)

    http://blog.csdn.net/lc_lc2000/article/details/53135839 本意是使A = B,B为一个列表,结果在后续对A的操作中,导致B中的值也改变了,才回忆起 ...

  3. python列表补充、循环

    优先掌握部分 切片l=['a','b','c','d','e','f']print(l[1:5])print(l[1:5:2])print(l[2:5])print(l[-1])了解print(l[- ...

  4. Python列表的切片操作

    在Python列表中分片是一个很重要的操作,有以下几个注意的点: 切片时不包含最后一位,如下例子中,要取最后一位,从0开始算应该是到7就可以取,但是需要8才能取 2.      默认取值步长为1,即每 ...

  5. Python—列表(一个“打了激素”的数组)

    我们在C语言中会使用数组来将一大堆数据类型一样的数据挨个摆在一起,但是数组有一个基本的要求,就是数据类型必须是一致的,我们知道Python的变量由于没有数据类型,也就是说Python没有数组这一概念, ...

  6. python列表与集合,以及循环时的注意事项

    一.python列表 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,往后数的最后一个为-1依此类推. Python有6个序 ...

  7. python3速查参考- python基础 3 -> -> while循环实例 + Continue && break的应用 + 列表的初步学习

    while语句的应用 实例如下: """ 述求:用户登录系统,最多只能登录三次 第三次失败后,程序终止 """ user_table = { ...

  8. 【Python笔记】2020年7月30日练习【python用input函数输入一个列表】

    练习课题链接:廖雪峰-Python教程-高级特性-迭代 学习记录: 1.Python当中类似于 三目运算符 的应用 2.Python用input函数输入一个列表 代码实例:对用户输入的一组数字转化成l ...

  9. Python 列表如何获得一个指定元素所在的下标

    在使用Python3.4读取txt数据到列表,由于编码问题,读取到的数据通常会出现'\ufeffX'(x为你想要的数据).这时候如果需要把列表中的数据由字符串转换到数值型的数据的进行数据分析的话就会出 ...

随机推荐

  1. WPF:自动执行"机器人"程序若干注意事项

    企业应用中,经常会遇到一些需要定时自动执行的程序来完成某些功能,比如:自动定时从第三方web service取回数据.定时对历史数据进行清理.定时向ftp上传业务数据... 这类程序,我习惯称为“机器 ...

  2. WPF 异步加载高清大图

    不管什么东西,但凡太大了,总是让人又爱又恨啊!(很有道理的样子,大家鼓掌└( ̄  ̄└)(┘ ̄  ̄)┘) 猿:老板,现在这社会啊,真是浮躁啊,之前还是什么1080P,然后就到了2K,现在又到了4K……他 ...

  3. 中晟银泰国际中心酒店式公寓介绍 业主交流QQ群:319843248

    行政区域:中原区 区域板块:西北板块 项目位置:中原路与华山路东北角(中原万达北侧中原西路对面) 建筑类型:高层 物业类别:酒店式公寓 户型面积:公寓35-100平米 开发商:中晟集团 投资商:中晟集 ...

  4. 优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案

    简介 本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge. 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发 ...

  5. CSS3——让最后一行显示省略号

    代码如下: <!DOCTYPE html> <html> <head> <title></title> <meta charset=& ...

  6. 【JQuery】 ajax 无效的JSON基元

    [如题]个人理解就是 你向传数据[josn格式]了,但是后台接受确不是json格式的 数据, 贴段代码 var strJson = '{ "usercode": "123 ...

  7. android 布局之scrollview

    今天在布局页面的时候后犯了难,我要显示的内容一个页面展示不完,怎么办呢? 于是随便找了个app点开一看,哎呀原来还能翻动啊!这是啥布局呢?原来是ScrollView 官方api相关的内容全是英文,这可 ...

  8. Spring MVC 相关资料整理

    来源于:http://www.cnblogs.com/ylhssn/p/4062757.html 1.概述 Spring MVC是一种基于Java实现MVC设计模式的请求驱动类型的轻量级Web框架,即 ...

  9. model 的验证

    Ext.onReady(function(){ Ext.define('User', { extend: 'Ext.data.Model', fields: [ { name: 'name', typ ...

  10. [转]响应式WEB设计学习(2)—视频能够做成响应式吗

    原文地址:http://www.jb51.net/web/70361.html 上集回顾: 昨天讲了页面如何根据不同的设备尺寸做出响应.主要是利用了@media命令以及尺寸百分比化这两招. 上集补充: ...