2016-05-01 10 views
0

私は完全な初心者で、最近はPythonを使うことを学んでいます 私のコードに問題があります。私はリストaddList場合は、アイテムの数をカウントしようとしているし、私は新しいキーを作成し、カウントを更新する場合は、その値のキーが存在する場合は、辞書の値に追加します。 問題は、複数のアイテムがあるリストで、1つのアイテムが複数回カウントされることにつながります。 私の戦略は、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'に反しないのですか? どうすれば修正できますか?私は、コミュニティが私は私の問題

を打破するために全力を試みたとして、私は、言って何を理解してほしい

は私を助けてくれてありがとう。代わりに、カウントをチェックし、setdefaultを使用しての

+0

SyntaxError:不正な入力( 'lst') '、別のエラーが表示されています。 – piyushj

+0

ここではゴールデンルールがあります:ループ内でループしているものを変更しないでください。 –

答えて

0

問題は繰り返しです。一般的に、for i in range(...)を実行することは、あなたが本当に項目だけでなくインデックスを本当に必要としない限り、Pythonの中で最善の選択肢ではありません。

あなたのケースでは、実際にあなたのコードを破壊します。あなたのforループは、ループが開始されたときに0から2番目から最後まで(more later this on this)のaddedItemsのインデックスです。。しかし、addItemsからアイテムを削除すると、アイテムが短くなります!したがって、ある時点で、ループはそこにないインデックスにアクセスしようとします。これは、あなたが '金貨'でindexErrorを取得する理由です。

「ルビー」はなぜ機能しませんか? rangeには最後の番号が含まれていないため、代わりにrange(0,len(addedItems))を使用する必要があります。したがって、あなたのコードでは、2番目から最後までの値にしかなりません。

この結果、アイテムを繰り返し処理する方がはるかに良いアイデアです。あなたの関数addToInventoryがに渡されます(変更可能=変更可能)インベントリを変更することにも

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 

注:項目が潜在的に辞書には存在しないに対処するために、あなただけのデフォルト値の0でgetメソッドを使用することができますそれは何も返さないので、Noneを返します。従ってinv = addToInventory(inv, dragonLoot)は、addToInventoryが実行されたときに実際にinvを変更し、次にinvからNoneに設定され、関数の戻り値!だから、ちょうどaddToInventory(inv, dragonLoot)を使いたいと思うでしょう。

+0

私を助けてくれてありがとう – user6277136

3

、単に新しいエントリを作成し、戦利品のリストを反復処理し、可能な場合は、適切なエントリに各項目を追加し、必要なとき:

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

行うための他の方法があります。 getsetdefaultcollections.defaultdict、および/またはcollections.Counterとなりますが、完全な初心者の方であれば、上記の方法がおそらく最も簡単でしょう。

inv = ...を再バインドする必要はありません。関数はinvを直接突き抜けます。参照を保存せずに呼び出します。

addToInventory(inv, dragonLoot) 
+0

'inventory'を返さなければなりません。そうしないと何も変わりません。 – Wentao

+0

@Rahn - 返却も返却もしないでください。そのエフェクトにノートを追加します。 – TigerhawkT3

+0

あなたが正しいとすれば、 'inv = addToInventory(inv、dragonLoot)'ではなく 'addToInventory(inv、dragonLoot)'を実行するだけです。 – Wentao

関連する問題