i recently wrote a method to cycle through /usr/share/dict/words and return a list of palindromes using my ispalindrome(x) method
here's some of the code...what's wrong with it? it just stalls for 10 minutes and then returns a list of all the words in the file
def reverse(a):
return a[::-1]
def ispalindrome(a):
b = reverse(a)
if b.lower() == a.lower():
return True
else:
return False
wl = open('/usr/share/dict/words', 'r')
wordlist = wl.readlines()
wl.close()
for x in wordlist:
if not ispalindrome(x):
wordlist.remove(x)
print wordlist
wordlist = wl.readlines()
When you do this, there is a new line character at the end, so your list is like:
['eye\n','bye\n', 'cyc\n']
the elements of which are obviously not a palindrome.
You need this:
['eye','bye', 'cyc']
So strip the newline character and it should be fine.
To do this in one line:
wordlist = [line.strip() for line in open('/usr/share/dict/words')]
EDIT: Iterating over a list and modifying it is causing problems. Use a list comprehension,as pointed out by Matthew.
Others have already pointed out better solutions. I want to show you why the list is not empty after running your code. Since your ispalindrome() function will never return True because of the "newlines problem" mentioned in the other answers, your code will call wordlist.remove(x) for every single item. So why is the list not empty at the end?
Because you're modifying the list as you're iterating over it. Consider the following:
>>> l = [1,2,3,4,5,6]
>>> for i in l:
... l.remove(i)
...
>>> l
[2, 4, 6]
When you remove the 1, the rest of the elements travels one step upwards, so now l[0] is 2. The iteration counter has advanced, though, and will look at l[1] in the next iteration and therefore remove 3 and so on.
So your code removes half of the entries. Moral: Never modify a list while you're iterating over it (unless you know exactly what you're doing :)).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With