[Tutor] detecing palindromic strings
Terry Carroll
carroll at tjc.com
Sat Sep 29 02:43:22 CEST 2007
On Fri, 28 Sep 2007, Christopher Spears wrote:
> I'm trying to write a script that detects if a string
> is palindromic (same backward as it is forward). This
> is what I have so far:
> my_str = raw_input("Enter a string: ")
> string_list = []
Here you are creating a list and assiging the name string_list to it.
> for s in my_str:
> string_list.append(s)
Now you've manipulated this list
> string_list_orig = string_list
Here is the problem: you're thinking you're creating another list, named
string_list_orig, which is a copy of string_list. you're not. What
you're actually doing is assigning another name, string_list_orig, to the
existing list that was created above.
> string_list.reverse()
Now you're reversing that single list.
> print string_list_orig
> print string_list
Now you're printing that list twice, once using each name.
>
> The problem is that the script gives results like so:
> io at io-station-1 ./chap6 117> python palindromic.py
> Enter a string: abc
> ['c', 'b', 'a']
> ['c', 'b', 'a']
Using your approach, the easiest quick fix is to replace the line:
string_list_orig = string_list
with:
string_list_orig = string_list[:]
This creates a new list by slicing from string_list, and assigns it a
name string_list_orig. Then you're dealing with two different lists,
and reversing one does not affect the other.
The notation string_list[:] produces a slice of a list. You usually see
it with numbers in there, a la:
>>> L = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
>>> L[2:5]
['C', 'D', 'E']
This slices from position 2 up to (but not including) position 5. ('A' is
at position 0).
The default for where to start is 0, so L[:5] is the same as L[0:5] :
>>> L[:5]
['A', 'B', 'C', 'D', 'E']
The default for where to end is the end of the list, so L[2:] is the same
as L starting at 2 and going to the end of the list:
>>> L[2:]
['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
Putting those two defaults together, leaving both the start and end out
means to start at the first element and go all the way to the end:
>>> L[:]
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
So that's what the funky [:] notation gets you.
> How do I get around this? Is there a better way to
> write this script? I can't figure out how to loop
> through a string starting from the last character.
You can slice strings the same way you can slice lists. And what's more,
you can specify a third parameter on the slice that specifies the stepping
of the slicing; the default is 1, but, for example, using 2 will select
every other element:
>>> S = "ABCDEFGHIJ"
>>> S[::2]
'ACEGI'
And, here's the thing: if you use a negative number for ttep, it works
from the right side of the string, rather than the left. So, if you use a
step of -1 you get:
>>> S[::-1]
'JIHGFEDCBA'
And that's the easiest way to reverse a string, rather than converting it
to a list and reversing the list.
More information about the Tutor
mailing list