Python 3 Index Error
<p>Consider the following code:</p>

<pre><code>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 &gt;&gt;&gt; ")
    str2 = input("Enter string #2 &gt;&gt;&gt; ")
    result = anadist(str1, str2)
    print(result)

#Boilerplate Check
if __name__ == "__main__":
    main()
</code></pre>

<p>Running in Python 3.5.2 raises an IndexError:</p>

<pre><code>Traceback (most recent call last):
  File "E:\CSE107L\Practice\anadist.py", line 34, in &lt;module&gt;
    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
</code></pre>

<p>And I can't find what is going wrong. I wrote another code similar and that works:</p>

<pre><code>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()
</code></pre>

<p>I feel the error is coming from the way I am forming <code>string1_list</code>. This code is for how many steps it takes to form an anagram of a pair of words.</p>

<p>Your second attempt works simply because a "match" is found only in the last element <code>5</code> and as such when you mutate your list <code>lst</code> it is during the <em>last iteration</em> and has no effect.</p>

<p>The problem with your first attempt is that you might remove from the beginning of the list. The counter doesn't get updated and at some point might reach a value that no longer exists in the list (it has been popped). Try running it with no matches in the input and see that it works.</p>

<p>In general, <em>don't mutate your list while iterating through it</em>. Instead of the: </p>

<pre><code>for i in range(len(lst)):
    # mutate list
</code></pre>

<p>'idiom', you should opt for the: </p>

<pre><code>for i in list(list_object):   # or for i in list_object[:]:
</code></pre>

<p>which makes a copy first and allows you to mutate the original <code>list_object</code> by keeping mutating and looping separate.</p>

python list python-3.5 anagram