2016-03-13 42 views
1

我在下面有這段代碼。第一個print語句打印出:for循環和在Python中的列表上打印的順序是什麼?

['c','a','t','d','o','g','r','a','b','b','i','t'] 

預期

wlist = ['cat','dog','rabbit'] 
llist = [letter for word in wlist for letter in word] 
tlist = [] 
print (llist) 
for item in llist: 
    if not item in tlist: 
      tlist.append(item) 
    else: 
      llist.remove(item) 
print (llist) 

第二個,我期待它打印:

['c','a','t','d','o','g','r','b','i'] 

但實際打印:

['c','d','o','g','r','a','b','b','i','t'] 

我不明白爲什麼。我正在試圖從llist中重複出現一封信。但第一次出現似乎被取消了,這兩個b仍然存在。任何人都可以向我解釋發生了什麼?

+1

請參見[在Python中迭代時從列表中刪除項目](http://stackoverflow.com/q/1207406),以便在迭代時正確刪除列表中的項目。 –

+0

如果您在每次迭代結束時嘗試「打印(llist)」,您會看到當您檢查兔子這個單詞的字母'a'時,'else'條件變爲真,它將命令刪除'llist'中的'a'。這會在'c'之後的第二個索引列表中刪除該字母的第一次出現。你需要做的是獲得你想要刪除的字母的索引,然後刪除所需索引上的字符。 – MrPyCharm

回答

0

問題是,您正在修改您正在迭代的列表,這會影響迭代器使用的指針。遍歷一個副本,而不是:

從你迭代列表
for item in llist[:]: 
    if item not in tlist: 
     tlist.append(item) 
    else: 
     llist.remove(item) 
+0

謝謝,我現在明白我的問題。但是你用[:]做了什麼?我猜這使得一個臨時列表迭代,然後在for循環結束時刪除臨時列表? – DDauS

+0

它通過切片創建一個新對象,該對象碰巧包含對原始元素的引用。現在,您正在迭代新的匿名列表,但修改了原始列表。 – chepner

1
else: 
    llist.remove(item) 

在這裏,你要刪除的項目。這通常會導致很多問題,因爲您將循環跳過元素。你應該總是避免改變你正在迭代的列表。

如果您完全刪除else的情況,您會得到所需的結果。畢竟,不需要修改源列表。

+0

酷感謝隊友。 – DDauS