天天看點

python list循環remove操作的神奇問題 推薦

在自動部署gpfs叢集當中,我需要排除系統盤,以及做raid資訊的磁盤。首先把目前伺服器所有磁盤放在一個清單裡,如a的值。然後把/proc/mdstat中的raid資訊放在另一個變量裡,如b的值。

a=['sda', 'sdc', 'sdd', 'sde', 'sdf']    

b='md127 : active raid1 sdd[1] sde[0]'

接下來循環a中的元素,如果這個字元串在b中存在,則删除a中的該元素。最後得到一個排除做了raid磁盤的清單a。

光人眼就可看出,a中元素sdd和sde在b中存在,但我循環清單a的時候,sde并沒有删除。好奇怪!見下面代碼:

>>> a=['sda', 'sdc', 'sdd', 'sde','sdf']

>>> a

['sda', 'sdc', 'sdd', 'sde', 'sdf']

>>> b

'md127 : active raid1 sdd[1] sde[0]'

>>> for i in a:

...  if iin b:

...  a.remove(i)

...

['sda', 'sdc', 'sde', 'sdf']

接下來調試,循環a清單,如果元素在b中,則列印出來,結果證明sdd,sde确實在b中。那為什麼用remove删除時,sde無法從清單中删除呢?調試代碼如下:

...  print i

sdd

sde

分析:

懷疑可能是使用remove時,字段位置進行了變化。

初始值a=['sda','sdc', 'sdd', 'sde', 'sdf'],當循環到sdd時,此時循環的值是a[2],比對了b中的内容,然後執行a.remove('sdd')操作。接下來for循環讀取a[3]中的内容:而此時a=['sda', 'sdc', 'sde', 'sdf'],a[3]的值是sdf了。中間的sde跳過去了!

是以才導緻最上面代碼中sde沒有删掉的情況!

解決方法:

把a中元素比對b中字元串的值,加入到清單c中。然後循環c,c中元素與a中一緻的,則删除a元素,這樣就不會導緻循環時跳過元素的問題。

解決代碼如下:

>>> b='md127 : active raid1 sdd[1]sde[0]'

>>> c=[]

...   c.append(i)

>>> c

['sdd', 'sde']

>>> for i in c:

... a.remove(i)

['sda', 'sdc', 'sdf']