2011-03-23 63 views
6

可能重複:
Remove items from a list while iterating in Python問題刪除列表項的for循環(蟒蛇)

喜IM有一個問題,我似乎無法刪除的項目,同時通過Python中的列表迭代, 這裏是我已經有了:一個標題應刪除,如果用戶輸入N或N當被問及在for循環中刪除的問題,問題是,當它完成所有的項目都依然存在,有沒有被刪除...

titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"] 

    for title in titles_list: 
     print "Do you want to keep the title:", title , "\n or Delete it ? Input Y for keep, N for Delete " 
     Question = raw_input() 
     if str(Question.upper) == "N": 
      titles_list.remove(title) 

print titles_list 
+0

同樣([在for循環或列表的Python奇怪的行爲]的DUP HTTP ://stackoverflow.com/q/742371/76705)。列表切片解決方案似乎更加pythonic。 – 2011-03-23 07:54:02

回答

10

下面的代碼將解決您的問題。您必須遍歷列表的副本。您無法從正在迭代的列表中刪除項目。

import copy 

def main(): 
    titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"] 
    titles_list_orig = copy.deepcopy(titles_list) 

    for title in titles_list_orig: 
     print "Do you want to keep the title:", title , "\n or Delete it? Input Y for keep, N for Delete " 
     Question = raw_input() 
     if str(Question.upper()) == "N": 
      titles_list.remove(title) 

    print titles_list 
+0

謝謝:D我使用拼接導致其較少的行,但是ü導致我需要複製它,謝謝 – RY4N 2011-03-23 06:53:10

+0

沒有必要複製它,只是反向迭代它,所以刪除不會影響你在迭代時看到的項目。 – ncoghlan 2011-03-23 07:05:36

+1

@ncoghlan - 請你詳細解答你的答案。對我不清楚。 – Sumod 2011-03-23 07:09:25

7

您的代碼實際上有兩個主要問題。

首先是你不是調用upper方法,但只是引用它。實際上你需要調用它(通過Question.upper())作爲w00t在他的回答一樣。

把你的循環裏面的一些診斷打印語句會一直看到(尤其是打印出str(Question.upper))的好方法(正切:Question是用於保存回答一個問題問的程序變量的壞名聲用戶)

其次,從你迭代將導致跳過值的列表中刪除已經看過的項目。你實際上並不需要複製整個列表處理這個 - 只是遍歷它是反向足以解決問題。

最後,一對夫婦的未成年人的美容點是raw_input()接受提示參數,所以你不需要單獨的打印語句,並在一個字符串調用upper()將本身總是返回一個字符串:

titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"] 
prompt = ("Do you want to keep the title: {}\n" 
      "or Delete it? Input Y for keep, N for Delete: ") 

for title in reversed(titles_list): 
    answer = raw_input(prompt.format(title)) 
    if answer.upper() == "N": 
     titles_list.remove(title) 

print titles_list 
+0

您可能想要提及的是,新的樣式字符串格式只能在python 2.7及更高版本中使用。 – 2011-03-23 07:34:37

+0

它實際上在2.6或更高版本中可用 – ncoghlan 2011-03-23 11:02:56

+0

但是,如果您需要使用2.5或更早版本,那麼格式化字符串中的「{}」需要被替換爲「%s」,並且格式化命令本身變爲'prompt% title'。 – ncoghlan 2011-03-23 11:47:05

1

我認爲你的代碼中的主要問題是上層函數的不正確使用。一旦你修好了,你可以隨意從列表中刪除標題。您可以使用索引或值。這裏是代碼剪切,我工作

 
#!/usr/bin/python 

import string 

titles_list = ["English", "Math", "Biology", "IT", "History"] 
for title in titles_list: 
    answer = raw_input("Do you want to keep this title %s, type y or n\n" % (title)) 
    if string.upper(answer) == "N": 
    # i = titles_list.index(title) 
    # del titles_list[i] 
    titles_list.remove(title) 
    print "now list is" , titles_list 
print titles_list 

請參閱使用索引註釋行。此外,您還可以使用的raw_input(提示)功能讓你的代碼更簡潔。

您還需要考慮在列表中出現多個相同標題的場景,在這種情況下,我建議獲取標題的所有索引,直到列表爲空,並使用del(index ),因爲上面提供的解決方案將只刪除標題的第一個出現。

+0

不需要使用'string'模塊 - 'answer.upper()'工作得很好。然而,你是否真的試過這個,看看每次按下'n'時會發生什麼?您將不會被提供從列表中刪除「Math」或「IT」的機會。 – ncoghlan 2011-03-23 11:49:33

0

我知道有一個答案已經,這裏是完整的另一種方式,並展示列表理解。

此方法需要一個清單,要求保持每個項目,並返回不包括標記爲刪除的那些新的列表:

def delete_items(titles): 
    deleted_items = [] 
    for title in titles: 
     print('keep %s?' % title) 
     if str(raw_input().upper()) == 'N': 
      deleted_items.append(title) 
    return [e for e in titles if e not in deleted_items]