2016-05-01 75 views
0

我是一個完整的初學者,最近學習使用python 我的代碼有問題。我正在嘗試計算列表的數量,如果列表addedList,然後將其添加到字典中的值,如果該值的關鍵存在,如果沒有我創建一個新的密鑰並更新計數。 問題在於,如果列表中存在多個項目,則可能會導致一個項目不止一次計數。 我的策略是使用remove方法從列表中刪除項目。 我相信這樣可以防止物品被計入多次。爲什麼我的for循環忽略一個項目?

但是,當我運行代碼它。我收到一個錯誤:IndexEror:索引超出範圍

def addToInventory(inventory, addedItems): 
    lst = list(addedItems) 
    for item in range(0, len(addedItems)-1): 
     count = lst.count(lst[item]) 
     if addedItems[item] in inventory: 
      inventory[lst[item]] += count 
      if count > 1: 
       for i in range(0, count): 
        word = lst[item] 
        addedItems.remove(word) 
     else: 
      inventory.setdefault(lst[item], count) 
inv = {'gold coin': 42, 'rope': 1} 
dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby'] 
inv = addToInventory(inv, dragonLoot) 
displayInventory(inv) 

我發現我刪除了所有物品後的金幣。我成功地將「匕首」添加到字典中,而不是「紅寶石」。

我想請某人解釋一下
爲什麼for循環無法調整爲'ruby'? 我該如何解決它?

我希望社會明白我在說什麼,因爲我盡力打破我的問題

謝謝你對我的幫助。

+0

我得到另一個錯誤'SyntaxError:壞輸入('lst')',你確定這是代碼? – piyushj

+0

這是一條黃金法則:不要修改循環內循環的東西。 –

回答

0

你的問題是與你的迭代。一般來說,做一個for i in range(...)不是python的最佳選擇,除非你真的需要索引,而不僅僅是項目。

然而,在你的情況下,它確實會破壞你的代碼。當循環開始時,for循環從0到倒數第二個(稍後的更多)索引的addedItems 。但是當你從addedItems中移除物品時,它會變短!因此,在稍後的某個時刻,您的循環將嘗試訪問不存在的索引。這就是爲什麼你得到'金幣'的indexError。

爲什麼'ruby'沒有工作?因爲range不包含最後一個數字:您需要改用range(0,len(addedItems))。因此,用你的代碼,你只能達到倒數第二的價值。

這樣做的最終結果是,它是一個更好的主意,只是通過項目迭代。爲了應對可能在字典中不存在的項目,你可以只使用get法的默認值爲0:

def addToInventory(inventory, addedItems): 
    for item in addedItems: 
     inventory[item] = inventory.get(item,0)+1 
inv = {'gold coin': 42, 'rope': 1} 
dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby'] 
addToInventory(inv, dragonLoot) 
print inv 

注意過你的函數addToInventory修改(可變=修改)則傳遞到庫存它,並且不返回任何東西,因此返回None。因此inv = addToInventory(inv, dragonLoot)實際上修改爲invaddToInventory運行,然後設置invNone,函數的返回值!所以你只需要使用addToInventory(inv, dragonLoot)

+0

非常感謝你幫助我 – user6277136

3

而不是檢查數量和使用setdefault,只需通過掠奪列表迭代和每個項目的可能時,添加到相應的條目,創建一個新的條目,必要時:

def addToInventory(inventory, addedItems): 
    for item in addedItems: 
     if item in inventory: 
      inventory[item] += 1 
     else: 
      inventory[item] = 1 

還有其他的方法可以做到這與get,setdefault,collections.defaultdict和/或collections.Counter,但如果你是一個完整的初學者,上述方法可能會最容易遵循。

請注意,不需要重新綁定inv = ...,因爲函數直接變異inv。說它不保存一個參考:

addToInventory(inv, dragonLoot) 
+0

你必須返回庫存,否則沒有任何變化。 – Wentao

+0

@Rahn - 它不應該被退回也不會反彈。我會爲此添加一個註釋。 – TigerhawkT3

+0

你是對的,那麼你可以做'addToInventory(inv,dragonLoot)'而不是'inv = addToInventory(inv,dragonLoot)' – Wentao