It's ...

Angus Rodgers twirlip at
Wed Jun 24 17:12:33 EDT 2009

On Wed, 24 Jun 2009 16:40:29 -0400, "J. Cliff Dyer"
<jcd at> 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 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
>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

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 - 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

More information about the Python-list mailing list