A common computer science exercise involves testing whether or not a given word is a palindrome; that is, whether it’s the same word if the characters are printed in reverse order. Usually this involves some sort of loop through the characters of the word, while comparing each with the corresponding character starting at the end. Since I’ve been playing with Python recently, and since Python has such interesting tools for slicing up strings in different ways, I decided to write a program like this in Python to see what I’d come up with.
Of course there are other ways to do this, maybe better ways (see the end of this post); this was just a first attempt. It looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #! /usr/bin/python import sys # test; is a word a palindrome? str = sys.argv[1].lower() if len(str)%2==0: if str[:len(str)/2]==str[len(str)/2:][::-1]: print str,"is a palindrome" else: print str,"is not a palindrome" else: if str[:len(str)/2]==str[len(str)/2+1:][::-1]: print str,"is a palindrome" else: print str,"is not a palindrome" |
This is a fairly elementary version of such a program; it will only test single words; that is, you could type a phrase in quotes as an argument, but unless it were character for character (including spaces and punctuation) a palindrome, it would come out false. It’s made for nice, simple palindromes like radar, racecar, ogopogo, level, detartrated, or aoxomoxoa.
Looking through the code to see what it does is basically a crash course in how Python allows you to slice up strings. Like many languages, Python automatically indexes a string; so, “hello”[0] would be “h” — “hello”[4] would be “o”.
Slicing works like this:
1 2 3 4 5 | >>>str="hello" >>>str[:2] "he" >>>str[2:] "llo" |
The actual syntax is technically string[start:finish] — leaving the start blank will start at 0, and leaving the finish blank will go to the end of the string.
Also, the [::-1] that you would have noticed in the code simply writes a given string in reverse. (Technically, the third value is the “step”, so [::-1] is simply saying “step through the entire string backwards”.) So in effect, what this program does is compare the first half of a string with the second half reversed, to see if they’re the same.
Which brings us to the simpler way to do it: if we can simply reverse a string like that, this whole program could have been:
1 2 3 4 5 6 7 8 9 10 11 | #! /usr/bin/python import sys # test; is a word a palindrome? str = sys.argv[1].lower() if str==str[::-1]: print str,"is a palindrome" else: print str,"is not a palindrome" |
Or, if you wanted to be very succinct:
1 2 3 | #! /usr/bin/python import sys; str=sys.argv[1].lower(); print str==str[::-1] |
Okay then. That’s enough Python geekery for one night. :-)
Note: the wise among you will chuckle when I admit that, yes, I really did write the longer, ridiculously more complicated version of the program first. I could use this to segue into how the simpler solution to any problem is rarely the first to occur to us, or how easy it is to get caught up in a “solution” (in this case, compare the first half to the reverse of the second half) and miss a simpler solution… but I’ll save that for some other day.
Another note: in my defense, my first attempt was probably remembered from a time I solved a problem like this with a for loop… in which case it could actually be more efficient to compare the first half of the string with the second half, because it means you don’t need to step through the whole thing.
0 Responses to “Fun with Python: finding simple palindromes”