2010-01-13 61 views
4

我有一個包含主題和每個主題都有連接時間的數組。我想比較列表中的每個主題。如果有兩個相同的主題,我想添加兩個主題的時間,並且還想刪除第二個主題信息(主題名稱和時間)。使用for循環刪除列表中的項目

但是,如果我刪除該項目,列表變得更短,我得到一個超出範圍的錯誤。我試圖使用subjectlegth-1將列表縮短,但這也行不通。

... 
    subjectlegth = 8 
    for x in range(subjectlength): 
     for y in range(subjectlength): 
      if subject[x] == subject[y]: 
       if x != y: 
        #add 
        time[x] = time[x] + time[y] 
        #delete 
        del time[y] 
        del subject[y] 
        subjectlength = subjectlength - 1 
+2

看看http://docs.python.org/tutorial /datastructures.html#functional-programming-tools – jldupont 2010-01-13 14:48:53

回答

8

迭代反了,如果可以的話:

for x in range(subjectlength - 1, -1, -1): 

,類似的還有y

+4

儘管這樣可以「解決」如何在迭代列表中刪除列表元素的問題,但更大的問題是您實際上在迭代列表時修改列表。每當你正在考慮這樣做,退一步看看是否可以通過構建一個具有所需值的新列表來解決問題。在這種情況下,你正在爲類似的主題收集時間值 - 認爲「字典」,這是一個更好的結構。如果使用Python 2.5或更高版本,請考慮「defaultdict」,它比dict.get()更易於使用。伊格納西奧·巴斯克斯 - 艾布拉姆斯的答案是正確的。 – PaulMcG 2010-01-13 15:32:35

6

最好的做法是使項目的一個新的列表中刪除,並走在列表之後將其刪除:

to_del = [] 
subjectlength = 8 
for x in range(subjectlength): 
    for y in range(x): 
     if subject[x] == subject[y]: 
      #add 
      time[x] = time[x] + time[y] 
      to_del.append(y) 

to_del.reverse() 
for d in to_del: 
    del subject[d] 
    del time[d] 
8

如果subject元素是可哈希:

finalinfo = {} 

for s, t in zip(subject, time): 
    finalinfo[s] = finalinfo.get(s, 0) + t 

這將導致subject: time鍵值對的字典。

+0

+1 - 這是原始問題的*真實*解決方案。 – PaulMcG 2010-01-13 15:27:30

2

另一種方法是重新創建主題和時間列表,使用字典總結重複主題的時間(我假設主題是字符串即可哈希)。

subjects=['math','english','necromancy','philosophy','english','latin','physics','latin'] 
time=[1,2,3,4,5,6,7,8] 
tuples=zip(subjects,time) 
my_dict={} 
for subject,t in tuples: 
    try: 
     my_dict[subject]+=t 
    except KeyError: 
     my_dict[subject]=t 
subjects,time=my_dict.keys(), my_dict.values() 
print subjects,time 
+0

瞭解dict.get()或甚至更好的collections.defaultdict。比嘗試更清潔 - 除KeyError之外。爲什麼要輸出keys()和values()?什麼項目()? – PaulMcG 2010-01-13 15:36:01

+0

我知道get和defaultdict,但不知道OP是否如此堅持一種假定知識較少的方法。至於keys()和values(),OP需要兩個單獨的列表,而items()返回(鍵,值)元組列表。 – MAK 2010-01-13 15:41:58

+0

@MAK - 足夠公平,只要你儘可能少地擾亂OP的原始設計。但是一個程序可以將匹配的數據值保存在單獨的列表中*真正應該重做爲使用字典。如果設計需要添加教師或房間號碼怎麼辦?是否應該通過添加更多對順序敏感的列表來添加這些內容?假設字典概念超出了他/她,你做OP是一種傷害。 – PaulMcG 2010-01-13 15:51:52

0

雖然是while循環肯定是這一個更好的選擇,如果你堅持使用for循環,一個可以代替list與無,或其他任何區分item元素將要刪除的,並在for循環後重新定義list。下面的代碼去除整數列表偶數元素:

nums = [1, 1, 5, 2, 10, 4, 4, 9, 3, 9] 
for i in range(len(nums)): 
    # select the item that satisfies the condition 
    if nums[i] % 2 == 0: 
    # do_something_with_the(item) 
    nums[i] = None # Not needed anymore, so set it to None 
# redefine the list and exclude the None items 
nums = [item for item in nums if item is not None] 
# num = [1, 1, 5, 9, 3, 9] 

在這個職位的問題的情況下:

... 
for i in range(subjectlength - 1): 
    for j in range(i+1, subjectlength): 
    if subject[i] == subject[j]: 
     #add 
     time[i] += time[j] 
     # set to None instead of delete 
     time[j] = None 
     subject[j] = None 
time = [item for item in time if item is not None] 
subject = [item for item in subject if item is not None]