2010-03-29 175 views
7

我想將一個列表的內容轉移到另一個,但它不工作,我不知道爲什麼不。我的代碼如下所示:迭代通過清單刪除項目,一些項目不刪除

list1 = [1, 2, 3, 4, 5, 6] 
list2 = [] 

for item in list1: 
    list2.append(item) 
    list1.remove(item) 

但是,如果我運行我的輸出看起來像這樣:

>>> list1 
[2, 4, 6] 
>>> list2 
[1, 3, 5] 

我的問題有三個方面,我想:這是怎麼回事,我該如何使它工作,我是否忽略了一個非常簡單的解決方案,如「移動」聲明或其他?

+0

感謝所有幫助人員 - 這是我做錯事情的一個簡明扼要的解釋,還有幾個修復選項,我將立即着手嘗試實施。 =) – potatocubed 2010-03-30 18:55:16

回答

8

原因是你從第一個列表中刪除(附加和),因此它會變小。所以迭代器在整個列表可以通過之前停止。

達到你想要的東西,這樣做:

list1 = [1, 2, 3, 4, 5, 6] 
list2 = [] 

# You couldn't just make 'list1_copy = list1', 
# because this would just copy (share) the reference. 
# (i.e. when you change list1_copy, list1 will also change) 

# this will make a (new) copy of list1 
# so you can happily iterate over it (without anything getting lost :) 
list1_copy = list1[:] 

for item in list1_copy: 
    list2.append(item) 
    list1.remove(item) 

list1[start:end:step]slicing syntax:當你離開開始空則默認爲0,當你離開年底空是可能的最高值。所以list1 [:]意思是裏面的一切。 (感謝Wallacoloo)

就像一些帥哥說的,你也可以使用extend-list -object的方法來將一個列表複製到另一個列表,如果這是你的意圖。 (但是我選擇了上面的方式,因爲這與你的方法很接近。)

由於你是python的新手,我有一些東西給你:Dive Into Python 3 - 它是免費和容易的。 - 玩的開心!

+1

解釋列表索引/切片的鏈接('list [:]'是列表切片的一個例子):http://docs.python.org/tutorial/introduction.html#lists – Ponkadoodle 2010-03-29 22:29:12

8

您在迭代時正在從list1中刪除項目。

這是要求麻煩。

試試這個:

>>> list1 = [1,2,3,4,5,6] 
>>> list2 = [] 
>>> list2 = list1[:] # we copy every element from list1 using a slice 
>>> del list1[:] # we delete every element from list1 
+2

list2 = []不需要 – 2010-03-30 06:01:55

1

究竟是ChristopheD說。

可以這樣做:

list1 = [1, 2, 3, 4, 5, 6] 
list2 = [] 

for item in list1: 
    list2.append(item) 

list1 = [] 

那將明確列表1。

編輯他/她已更新他們的帖子。我會把它作爲一個輕微的選擇。

3

在迭代它時,不應該修改列表。這會導致迭代器指向錯誤的項目。在處理第一個項目之後,迭代器指向index = 1,但由於您已經刪除了一個項目,下一個項目現在處於索引零,因此它將被跳過。這就是爲什麼你只處理其他項目。

嘗試:

list2.extend(list1) # This appends all items from list1 to list2. 
del list1[:] # From ChristopheD's post. 
+0

對downvoter:downvote的原因是什麼?如果我的帖子中有錯誤,我想知道它是什麼,以便我可以爲將來學習。 – 2010-03-29 22:55:59

1

使用列表理解:

list2 = [item for item in list1] 

綁定名稱list2到爲list1相同的對象:

list2 = list1 

(請注意,如果您修改list1,list2的內容將b È相應變化)

創建的list1副本,並將其綁定到名稱list2

list2 = list1[:] 

在這種情況下列表1和list2中是不同的對象。

+0

第二個選項不會像你想象的那樣工作(特別是因爲你想刪除list1的項目) – ChristopheD 2010-03-29 21:57:59

+0

@ChristopheD:對不起,我的回答不明確。當我說將名稱list2綁定到與list1相同的對象時,我假定OP會知道list2和list1是同一個對象的兩個名稱。 – 2010-03-29 22:03:07

+0

對不起,我可能誤讀/誤解了你的答案,然後 – ChristopheD 2010-03-29 22:06:30

1

試試這個:

list1 = [1, 2, 3, 4, 5, 6] 
list2 = [] 

list2.extend(list1) 
list1[:] = [] 
4

基本調試技巧:添加print語句。 (在Python 3或print功能)

>>> list1= [1, 2, 3, 4, 5, 6] 
>>> for item in list1: 
...  print item 
...  list1.remove(item) 
...  print list1 
... 
1 
[2, 3, 4, 5, 6] 
3 
[2, 4, 5, 6] 
5 
[2, 4, 6] 

注意,Python是試圖逐步通過位置列表,但你保持刪除項目從列表,使得位置變得毫無意義。

Python從列表中選取位置0處的項目。

然後您刪除該項目,更改列表。

然後Python在挑選從列表中位置1項(出現跳過的項目)

您然後刪除項目,更改列表。

然後Python在挑選從列表中位置2項(出現跳過的項目)

然後,您刪除的項,改變名單。

然後Python會選擇位置3上的項目,但是沒有這樣的項目。所以循環停止。

1

還有一個不起眼的複印功能(或deepcopy的,如果你的列表中有複雜的對象,而不僅僅是整數):

from copy import copy 

list2 = copy(list1) 

如果你解釋你想要什麼,你可能會得到一個更合適的答案來完成(除非你只是學習python列表)。

在Python中的「變量」只是名稱/引用,所以你似乎想要做的破壞性副本似乎有點奇怪。如果你想list2中具有相同的值列表1,你可以這樣做:

list2 = list1 # now they are both referring to the same list 

及後若你想用列表1別的東西,你可以這樣做:

list1 = ['A', 'B', 'C'] 
+0

然後list2也是' ['A','B','C']'。問題是:爲什麼有兩個列表然後;-) – ChristopheD 2010-03-29 22:05:33

+0

@ChristopheD:list2不會改變 - 我剛剛檢查。新的列表對象正在創建並綁定到名稱list1,而不會影響list2。 – 2010-03-29 22:17:45

+0

@PreludeAndFugue:嗯,好點(如果沒有正確的思考,判斷得太早) – ChristopheD 2010-03-29 22:21:50

1

正如你可以在其他答案中看到,您正試圖修改列表,同時迭代它。這不起作用。有很多方法可以將一個列表複製到另一個列表。我做了一些測試,看看每種方法有多快:

>>> timeit.Timer('list2 = list1[:]', 'list1 = range(10**3)').timeit(10**6) 
3.9134418964385986 

>>> timeit.Timer('list2 = []; list2.extend(list1)', 'list1 = range(10**3)').timeit(10**6) 
4.9082601070404053 

>>> timeit.Timer('list2 = copy.copy(list1)', 'import copy; list1 = range(10**3)').timeit(10**6) 
7.5023419857025146 

>>> timeit.Timer('list2 = [i for i in list1]', 'list1 = range(10**3)').timeit(10**6) 
95.697894811630249 

切片語法是最快的。這比使用列表理解要快得多。

要清除列表,你可以使用:

del list1[:] 
0

@potatocubed:許多給出的答案解決您給簡單的例子(「移動列表1到列表2」),但真的不解釋「爲什麼」更深層次的問題,即在迭代它時修改列表。研究S.Lott的答案......