zoukankan      html  css  js  c++  java
  • 踩的python列表及for循环一个坑儿

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

    完事儿!!!

  • 相关阅读:
    Day2----Python常用模块
    Day1--Python基础知识
    AES加密
    MOS管基本MOS管基本认识(快速入门)认识(快速入门)
    printf定义宏方便调试
    ESP8266上电透传与手动透传AT指令设置笔记
    三态门与高阻态
    步进电机原理
    关于stm32 MCU申请动态内存malloc的认识
    高低位数据分离的两种方法
  • 原文地址:https://www.cnblogs.com/pycode/p/keng.html
Copyright © 2011-2022 走看看