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

 

完事兒!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM