I’m fairly new to Python and I’m trying to write a program that will
automatically come up with a list of words that will complete the New
York Times Spelling Bee game. For this project I have a .txt file
containing a large number of words (about 450,000). The Python script
is in theory supposed to take every word on the list containing a
certain letter. From there it would remove items from the list if they
contain a letter that is not used in the game. In the end it should
print out a list of these words for the user to enter.
My problem is that as I am trying to remove extra items from the list, I’ll get the error:
IndexError: list index out of range
Please paste the complete traceback. This pinpoints the line in your
code where the error occurred, rather than requiring us to scan your
entire programme.
Comments inline below.
Although I get this error, I don’t see the problem with my code. If someone could help me that would be great. Thanks!
Here is my code:
letterList = ['a', 'b', 'c', 'd', 'e', 'f']
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
centerLetter = 'g'
loopNumber = 0
while True:
position = alphabet.index(letterList[loopNumber])
alphabet.pop(position)
loopNumber = loopNumber + 1
if loopNumber == 6:
break
There’s a shorter way to write this loop, which avoids knowing the magic
number “6”:
for letter in letterList:
position = alphabet.index(letterList[loopNumber])
alphabet.pop(position)
This just iterates over letterList, assigning each letter to “letter”.
position = alphabet.index(centerLetter)
alphabet.pop(position)
loopNumber = 0
loopNumber2 = 0
loopNumber3 = 0
file1 = open(“WordList.txt”)
flag = 0
index = 0
listOfLines =
string1 = centerLetter
while True:
for line in file1:
index += 1
if string1 in line:
flag = 1
listOfLines.append(line)
if index == 370103:
break
break
It isn’t clear why you have a while-loop here at all. It always runs
exactly once (courtesy of the “break” at the bottom. You can drop the
while-loop entirely and just go:
for line in file1:
index += 1
if string1 in line:
flag = 1
listOfLines.append(line)
if index == 370103:
break
stuffToPop =
while True:
loopNumber3 = 0
loopNumber2 = 0
while True:
listOfLines2 = listOfLines
This may not do what you think. I imagine you want a copy of
listOfLines in listOfLines2. However, Python variables are references to
objects. So the result of the above is that listOfLines2 references the
exact same list as listOfLines. If you modify listOfLines2, listOfLines
is also modified because it is the same object (the original list).
Try this instead:
listOfLines2 = listOfLines.copy()
since lists come with a handy copy method for just this kind of thing.
if alphabet[loopNumber] in listOfLines[loopNumber2]:
print(loopNumber2)
stuffToPop.append(loopNumber2)
loopNumber3 = loopNumber3 + 1
loopNumber2 = loopNumber2 + 1
if loopNumber2 == len(listOfLines2) + 1:
break
I suspect this is your IndexError problem.
This allows loopNumber2 to be used when it is equal to
len(listOfLines2)
. But because lists (and other sequences) in Python
count from 0, the valid indices of listOfLines2 run from 0
through to
len(listOfLines2)-1
. So the iteration with
loopNumber2=len(listOfLines2)
will try to access
listOfLines[loopNumber2], which is also listOfLines[len(listOfLines2)]
on that loop iteration. That is out of bounds.
You if-statement wants to test if loopNumber2 == len(listOfLines2):
,
dropping the +1
.
But a better way to do this looks like this:
for loopNumber2, line in enumerate(listOfLines):
if alphabet[loopNumber] in line:
print(loopNumber2)
stuffToPop.append(loopNumber2)
This iterates over enumerate(listOfLines)
, a built in function which
itself iterates over listOfLines
and yields (index,item)
pairs for
each item in listOfLines
. So it yields:
0, listOfLines[0]
1, listOfLines[1]
2, listOfLines[2]
... and so on ...
which we assign to loopNumber2,line
in the for-loop. This means you
(a) don’t need to do fiddly loopNumber2=loopNumber2+1
stuff and (b)
don’t need to test loopNumber2
against the length of the list - the
for-loop will run the correct number of times all on its own, because
the list itself defines what the loop iterates over.
[…snip…]
loopNumber = 0
while True:
listOfLines.pop(loopNumber)
loopNumber = loopNumber + 1
print(“\n \n \n \n”)
print(“Lists of words”)
print(listOfLines)
Are you sure you want to do this while-True? It will run forever!
Cheers,
Cameron Simpson cs@cskk.id.au