2016-10-14 11 views
0

は、次のコードを考えてみましょう:Pythonの3インデックスエラー

Traceback (most recent call last): 
    File "E:\CSE107L\Practice\anadist.py", line 34, in <module> 
    main() 
    File "E:\CSE107L\Practice\anadist.py", line 29, in main 
    result = anadist(str1, str2) 
    File "E:\CSE107L\Practice\anadist.py", line 15, in anadist 
    if (string1_list[i]) in string2_list: 
IndexError: list index out of range 

を私は間違って何が起こっているかを見つけることができません。

def anadist(string1, string2): 
    string1_list = [] 
    string2_list = [] 

    for i in range(len(string1)): 
     string1_list.append(string1[i]) 
    for i in range(len(string2)): 
     string2_list.append(string2[i]) 

    # Test returns for checking 
    # return (string1_list,string2_list) 
    # return len(string1_list) 
    # return len(string2_list) 

    for i in range(0,len(string1_list)): 
     try: 
      if (string1_list[i]) in string2_list: 
       com = string1_list.pop(i) 
       com_index = string2_list.index(com) 
       string2_list.pop(com_index) 
      else: 
       pass 
     except ValueError: 
      pass 
    return string1_list 


def main(): 
    str1 = input("Enter string #1 >>> ") 
    str2 = input("Enter string #2 >>> ") 
    result = anadist(str1, str2) 
    print(result) 

#Boilerplate Check 
if __name__ == "__main__": 
    main() 

のPython 3.5.2で実行すると、IndexErrorを返しました。私は似た別のコードを書き、それが動作します:

def main(): 
    lst = [1,2,3,4,5] 
    lst2 = [5,6,7,8,9] 
    for i in range(len(lst)): 
     if lst[i] in lst2: 
      com = lst.pop(i) 
      lst2_index = lst2.index(com) 
      lst2.pop(lst2_index) 
     else: 
      pass 
    print(lst) 

if __name__ == "__main__": 
    main() 

私はエラーが私はstring1_listを形成してい道から来ている感じ。このコードは、一対の単語のアナグラムを形成するために必要なステップ数です。

+0

リストを反復処理するときに、リスト内の要素を削除することはできません。あなたのコードでは、リストは 'string1_list'です –

答えて

3

あなたはそれを反復処理している間、いくつかのケースでは、あなたがstring_list1を短縮している。

if (string1_list[i]) in string2_list: 
    com = string1_list.pop(i) # string1_list gets shorter here 

しかし、あなたのrangeは変更されません。 0からまでのの長さがstring1_list(排他的)までカウントされます。これにより、いつでもstring1_list.pop(i)が呼び出され、IndexErrorが発生します。

一つの可能​​な解決策ではなくwhileループを使用することです:

i = 0 
while i < len(string1_list): 
    try: 
     if string1_list[i] in string2_list: 
      com = string1_list.pop(i) 
      com_index = string2_list.index(com) 
      string2_list.pop(com_index) 
     else: 
      pass 
    except ValueError: 
     pass 
    i += 1 

この

は、ループ終了条件は各反復後にチェックされることになります。 string1_listからいくつかの要素を削除すると、ループが終了して iが十分に大きくなってそのコンテナの境界を越えてしまうので、それでも問題はありません。

1

あなたの問題は、string1_list.pop(i)を実行してforループ内のstring1_listに突然変異を起こしていることです。リストの長さは、string1_list.pop(i)を実行してforループ内で縮小されていますが、元のリストの長さにわたって繰り返しています。

ループの最後の反復でpopしかないため、2番目のコードが多く動作します。 「試合は」最後の要素だけ5で発見され、あなたがあなたのリストlstを変異させたときのような、それは最後の反復の間で、効果はありませんので、

1

あなたの第二の試みは、単純に動作します。

最初の試みでの問題は、リストの先頭から削除する可能性があることです。カウンタは更新されず、リストに存在しなくなった値に到達することもあります(ポップされています)。入力に一致するものがない状態で実行してみてください。

一般には、反復処理中にリストを変更しません。代わりに:

for i in range(len(lst)): 
    # mutate list 

「イディオム」、あなたはを選ぶ必要があります:最初のコピーを作成し、あなたが変異を維持し、別のループで元list_objectを変異させることができます

for i in list(list_object): # or for i in list_object[:]: 

を。

関連する問題