[Tutor] MemoryError
Jeff Shannon
jeff at ccvcorp.com
Wed Dec 8 21:29:10 CET 2004
Liam Clarke wrote:
> Hi all,
>
> I'm playing with a file, and attempting to replace a section with a
> string, and using the following command -
>
> seg=codeSt[element:endInd+len(endStr]
> codeSt=codeSt.replace(seg, hrefString)
>
> At the replace, I get a MemoryError. It's part of a for loop, but it
> gives the error the first time around.
I'm not sure why you're getting the MemoryError, but it'd be easier to
figure out if you posted the entire text of the traceback.
A few other pointers --
You'll probably get better performance if you put all of this code
inside of a function. Even if you're only running it once, putting it
in a function allows the interpreter to do some optimization tricks on
locals() which can't be done at the module-global level (where you're
running now). It's just barely possible that just doing this will
help with your MemoryError problem. (You would probably benefit from
splitting it into multiple functions, actually. I'd have the code
that finds text and url values each in their own function, for example.)
Try adding a line in between those two that prints out the value of
element and endInd, and then check that those numbers really are valid
indexes into codeSt. While you're at it, print out hrefString and
make sure it looks like it's supposed to.
At the start of your program, you have the following:
inp=file("toolkit.txt","r")
codeSt=inp.readlines()
inp.close()
codeSt="".join(codeSt)
Since you're not processing by lines, and are explicitly joining all
the lines together, why have Python separate them for you? It would
be much more efficient to simply use 'codeSt = inp.read()', with no
need to join() afterwards. The readlines() method effectively does a
read() followed by splitting the result into lines; for your purposes,
there's no point in splitting the lines if you're just going to join()
them immediately.
Instead of finding the start and end index of the segment you want to
replace, making a copy of that segment, and then scanning your
original string to replace that segment with a new chunk, it would
probably make more sense to simply grab codeSt before the segment and
after the segment and concatenate them with the new chunk. Thus, your
two lines above become
codeSt = codeSt[:element] + hrefString \
+ codeSt[endInd+len(endStr)]
Once again, this would avoid doing the same work twice.
> Now, I had imagined that codeSt=codeSt+10 would destroy the old codeSt
> in memory and create a new codeSt. Am I right?
Actually, this will probably raise a TypeError (cannot concatenate
'str' and 'int' objects). ;) But yes, rebinding codeSt to a new
string should allow the old string to be destroyed (if there are no
other references to it).
Hope that this helps.
Jeff Shannon
Technician/Programmer
Credit International
More information about the Tutor
mailing list