As others have said as you remove items the list gets shorter causing an index error.
Keeping in line with the original question. if your looking to remove items using list.remove() you can add the found items to a list then iterate over them and remove them from your original list like so:
# Set up the variables
test = ['aac', 'aad', 'aac', 'asd', 'msc']
found = []
# Loop Over the range of the lenght of the set
for i in range(len(test)):
try:
if test[i].startswith(test[i+1][0:2]):
found.append(test[i]) # Add the found item to the found list
except IndexError: # You'll hit this when you do test[i+1]
pass
# Remove the Items at this point so you don't cause any issues
for item in found:
test.remove(item) # If an item has been found remove the first instance
# This sholuld output only ['aac', 'asd', 'msc']
print test
EDIT:
As per Martins comment, you don't need to make a second list of items that need to be removed you can instead make a list of items that didn't need to be removed like so:
# Set up the variables
test = ['aac', 'aad', 'aac', 'asd', 'msc']
found = []
# Loop Over the range of the lenght of the set
for i in range(len(test)):
try:
if not test[i].startswith(test[i+1][0:2]):
found.append(test[i]) # Add the found item to the found list
except IndexError: # You'll hit this when you do test[i+1]
found.append(test[i]) # If there is no test[i+1], test[i] must be cool.
# This sholuld output only ['aac', 'asd', 'msc']
print found