標籤:python 演算法
問題描述:採用python實現剔除列表中相同的元素。顧名思義,比如說有一列表listVal = [12, 34, 23, 12, 23, 34, 15],經過剔除之後,應該只剩下listVal = [15]。
起初,我的思路是這樣的:遍曆每一個元素a(稱之為大的遍曆),記元素a的位序為LocA,對於每一個元素再做遍曆(小的遍曆),小的遍曆中應該是這樣執行的:在LocA直到列表結尾尋找跟a相同的位序SameLocA,如果找到了,則刪除找到的SameLocA對應的元素跟a;如果沒找到,則遍曆下一個元素;一直這樣做下去。下面即為代碼:
listVal = [12, 34, 23, 12, 23, 34, 15]
print ‘原先列表中的元素; ‘, listVal
i = 0
while i < len(listVal)-1:
if listVal[i] in listVal[i+1:len(listVal)]:
# 說明一定有相同的元素
pos = listVal.index(listVal[i], i+1, len(listVal))
del listVal[i]
del listVal[pos-1]
i = i
else:
i += 1
print ‘剔除相同元素之後的列表: ‘, listVal
然後運行結果如下:
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/70/E4/wKioL1XAvCLTm_6tAAB7gWSiUMg587.jpg" title="Image 3.png" alt="wKioL1XAvCLTm_6tAAB7gWSiUMg587.jpg" />
感覺上像是對了,有點小興,然後,隨意換了一組測試資料listVal = [12, 34, 23, 12, 32, 34, 12, 34, 56, 56, 56, 56, 23, 1, 1, 1, 1, 1, 0],竟然不對勁了,如:
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/70/E8/wKiom1XAuxfxs5TlAAChpDtiGTM631.jpg" title="Image 4.png" alt="wKiom1XAuxfxs5TlAAChpDtiGTM631.jpg" />
研究了一下代碼,對代碼加斷點調試,才發現:原因在於每次找到的相同的資料元素只能找到第一個。所以就換了想法:應該是需要找到LocA之後的所有的與a相同的元素,並將其刪除。這種想法外表上看沒啥問題,但實現起來,代碼卻有點令人費解:
listVal = [12, 34, 23, 12, 32, 34, 12, 34, 56, 56, 56, 56, 23, 1, 1, 1, 1, 1, 0]
print ‘原先列表中的元素; ‘, listVal
i = 0
while i < len(listVal)-1:
if listVal[i] in listVal[i+1:len(listVal)]:
# 說明一定有相同的元素
count = listVal[i+1:len(listVal)].count(listVal[i])
j = 0
start = i+1
while j < count:
pos = listVal.index(listVal[i], start, len(listVal))
start += pos
del listVal[pos-1]
j += 1
del listVal[i]
#del listVal[pos-1] # 還有bug:原因在於每次找到的相同的資料元素只能找到第一個.---這就是問題所在
i = i
else:
i += 1
print ‘剔除相同元素之後的列表: ‘, listVal
結果發現,老是出現數組下標越界,一直都想不通這是為什麼,斷點調試了之後還是不能發現。。。直到吃飯時間還是不能想出來,沒辦法,先填飽肚子先。於是一邊走在路上,一邊在想這個問題:覺得大的“架構”沒啥錯,問題出在哪裡呢,後來在拿著外賣回來的路上,腦袋一錚亮,終於想明白了幾點:
一:是len在每一次del之後是會使得列表中的元素個數以及位序發生重組,所以總的遍曆過程以及之後的i需要進行相應的變化
二:沒必要去找LocA之後的切片列表中是否存在跟a相同的元素,而可以直接的在總的列表中尋找a,擷取總的列表跟a相同的元素的個數count,然後只需要進行count次迴圈的一次del操作,因為每次進行del操作之後,列表將進行重組,只需要趕在i的位序發生變化之前找到與a相同的元素的位置,然後進行del即可。
一下是我想了許久的代碼,覺得很有意思,並不是說這個問題有多進階,也不是說這個問題有多難,代碼有進階,而是我覺得這個思考的過程讓我覺得很是刺激,興奮,我喜歡這樣的體驗,哪怕是花很長時間。
# 終於正確的實現了
# listVal = [12, 34, 23, 1, 12, 32, 34, 1, 1, 12]
listVal = [12, 34, 23, 12, 32, 34, 12, 34, 56, 56, 56, 56, 23, 1, 1, 1, 1, 1, 0]
#listVal = [12, 34, 23, 12, 23, 34, 15]
print ‘原先的元素: ‘, listVal
i = 0
count = 0
while i < len(listVal):
value = listVal[i]
count = listVal[0:len(listVal)].count(value)
#print count
if 1 < count:
j = 0
while j < count:
#這裡就是容易出錯的地方:雖然len以及知道會發生動態變化,但差點就忽略了del也會讓列表中元素位序發生變化。後來
#吃飯的路上一直都在想。。。。打個外賣回來的路上竟然想到了,嘻嘻。。。。
del listVal[listVal.index(value)]
j += 1
#這裡也是關鍵:因為一旦刪了元素a的位序LocA就會立馬發生變化,噹噹前元素a被刪了時候,
# 需要將其位序賦值給下一個元素b以保證b為當前列表中的LocA即 i=i;否則就代表壓根沒有相同的元素,則 i+=1 #
# 即進行下一個元素的操作
i = i
else:
i += 1
print ‘之後的元素‘, listVal
運行結果:
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/70/E5/wKioL1XAwhmhWwGaAACOD0sifUk907.jpg" title="Image 7.png" alt="wKioL1XAwhmhWwGaAACOD0sifUk907.jpg" />
以上還涉及列表的索引,分割等操作,就不再囉嗦了,自己可以百度或者上python教程看看。
歡迎諸位提出評論!
本文出自 “我的Awesome部落格” 部落格,請務必保留此出處http://steadyjcak.blog.51cto.com/8027674/1681719
用Python實現剔除列表中相同的元素