On Wed, 24 Jun 2009 16:40:29 -0400, "J. Cliff Dyer" <j...@sdf.lonestar.org> wrote:
>On Wed, 2009-06-24 at 20:53 +0100, Angus Rodgers wrote: >> [...] >> from types import StringType # Is this awkwardness necessary? > >Not anymore. You can just use str for this. > >> detab = lambda s : StringType.expandtabs(s, stop) # Or use def > >First, use def. lambda is a rarity for use when you'd rather not assign >your function to a variable. > >Second, expandtabs is a method on string objects. s is a string object, >so you can just use s.expandtabs(stop) How exactly do I get detab, as a function from strings to strings (for a fixed tab size)? (This is aside from the point, which you make below, that the whole map/join idea is a bit of a no-no - in some other context, I might want to isolate a method like this.) >Third, I'd recommend passing your tabstops into detab with a default >argument, rather than defining it irrevocably in a global variable >(which is brittle and ugly) No argument there - I was just messing about in the interpreter, to see if the main idea worked. >> f = open('h071.txt') # Do some stuff to f, perhaps, and then: >> f.seek(0) > >f is not opened for writing, so if you do stuff to the contents of f, >you'll have to put the new version in a different variable, so f.seek(0) >doesn't help. If you don't do stuff to it, then you're at the beginning >of the file anyway, so either way, you shouldn't need to f.seek(0). I seemed to find that if I executed f.xreadlines() or f.readlines() once, I was somehow positioned at the end of the file or something, and had to do the f.seek(0) - but maybe I did something else silly. >> print ''.join(map(detab, f.xreadlines())) > >Sometime in the history of python, files became iterable, which means >you can do the following: > >for line in f: > print detab(line) > >Much prettier than running through join/map shenanigans. This is also >the place to modify the output before passing it to detab: > >for line in f: > # do stuff to line > print detab(line) > >Also note that you can iterate over a file several times: > >f = open('foo.txt') >for line in f: > print line[0] # prints the first character of every line >for line in f: > print line[1] #prints the second character of every line >> f.close() This all looks very nice. >> For writing the output file, this seems to work in the interpreter: >> >> g = open('temp.txt', 'w') >> g.writelines(map(detab, f.xreadlines())) >> g.close() >> > >Doesn't help, as map returns a list. Pity. Oh, well. >You can use itertools.imap, or you >can use a for loop, as above. This is whetting my appetite! >The terms to look for, rather than opaque sequence objects are >"iterators" and "generators". OK, will do. >Glad you're enjoying Beazley. I would look for something more >up-to-date. Python's come a long way since 2.1. I'd hate for you to >miss out on all the iterators, booleans, codecs, subprocess, yield, >unified int/longs, decorators, decimals, sets, context managers and >new-style classes that have come since then. I'll get either Beazley's 4th ed. (due next month, IIRC), or Chun, /Core Python Programming/ (2nd ed.), or both, unless someone has a better suggestion. (Eventually I'll migrate from Windows 98SE(!), and will need info on Python later than 2.5, but that's all I need for now.) -- Angus Rodgers -- http://mail.python.org/mailman/listinfo/python-list