« November 2009
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
     
       
Today
XML

Neat blogs

Navigation

Editing

Powered by Roller Weblogger.

statcounter.com

clustrmaps.com

Locations of visitors to this page

technorati.com

20081008 Wednesday October 08, 2008
Python strings are Immutable

So I added some code to my simple script that wasn't in the Perl:

for line in open(sys.argv[1]):
        line.lstrip()

And my intent was to strip out all of the leading spaces. I didn't have to, but I created a simple test case with the first line pushed over by a tab and the second line pushed over by 8 spaces. The first one worked correctly and the second did not:

Update, I wasn't thinking correctly here, I knew I had two bad lines here and I didn't know why. After solving the coding problem, I can see that both lines of input failed. The header line is being treated here as if it were a normal line and being processed.

> ./simple2.py r2.txt
        !started - ended: title for company
        description



     1/05 - present: Staff Engineer Software for Sun Microsystems
        NFS development

Well d'oh, even in Perl I just told it to strip out one character. I've got to tell it that while there is whitespace, strip it out:

for line in open(sys.argv[1]):
        while line.isspace(): line.lstrip()

And this doesn't work either. At which point I realize it must be because strings are immutable, right? I mean it is never changing! Note I get to the right conclusion, but for the wrong reasons. If it were immutable and the string had whitespace at the start, I should be stuck in an endless loop here. See the ending section for that analysis.

It also points out that I never did anything with that line.lstrip(). It never changes line, but does create a reference to a new string. Which we can see here:

>>> st2 = "     This is the radio clash!"
>>> print st2.lstrip()
This is the radio clash!
>>> print st2
     This is the radio clash!
>>>

See, st2.lstrip() actually works!

I've fixed up the script (in a boring way) and it works:

for line in open(sys.argv[1]):
        line2 = line.lstrip()
        if line2.startswith("!") or line2.startswith("#"): continue
        print "%s - %s: %s for %s\n\t%s\n\n" % tuple(line2.split(","))

Another mistake I just made

Okay, to try to understand this, I did the following in the shell:

>>> st2 = "     This is the radio clash!"
>>> while st2.isspace():
...     print st2
...     st2.lstrip()
...

Which should be an endless loop according to what I know now. But nothing gets done. Which means that st2.isspace() is FALSE. And a help(st2.isspace) shows that:

Help on built-in function isspace: isspace(...) S.isspace() -> bool Return True if all characters in S are whitespace and there is at least one character in S, False otherwise.

I.e., my misunderstanding of st2.lstrip() being immutable made me think that st2.isspace() worked on the first character of the string. Actually, I made a bad assumption based on what I thought C would do. My bad.

So I don't ever want to do that while loop on a string which is really all whitespace.

All the reading in the world about Python strings will not help me understand the immutability of them as much as this simple example.


Originally posted on Kool Aid Served Daily
Copyright (C) 2008, Kool Aid Served Daily

Trackback URL: http://blogs.sun.com/tdh/entry/python_strings_are_immutable
Comments:

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed