• 踩的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}]

    完事儿!!!

  • 相关阅读:
    dotnet core 获取 MacAddress 地址方法
    dotnet core 获取 MacAddress 地址方法
    dotnet core 发布只带必要的依赖文件
    dotnet core 发布只带必要的依赖文件
    Developing Universal Windows Apps 开发UWA应用 问答
    Developing Universal Windows Apps 开发UWA应用 问答
    cmd 如何跨驱动器移动文件夹
    cmd 如何跨驱动器移动文件夹
    C++ 驱动开发 error LNK2019
    C++ 驱动开发 error LNK2019
  • 原文地址:https://www.cnblogs.com/pycode/p/keng.html
Copyright © 2020-2023  润新知