[Python-Dev] Optional separatorargument for file.writelines()and StringIO.writelines()

Moore, Paul Paul.Moore at atosorigin.com
Wed Feb 25 08:37:05 EST 2004


From: Alex Martelli
> On 2004 Feb 25, at 12:13, Dmitry Vasiliev wrote:

>> Raymond Hettinger wrote:
>>> Currently, writelines() does not add trailing line separators..
>>> This is fine when working with readlines() but a PITA in other 
>>> situations.
>>> If we added an optional separator argument, it would be easier to add
>>> newlines and we would gain some of the flexibility of str.join() at 
>>> full C speed.
>>
>> Maybe not a separator but suffix, so newline will be added to last 
>> line too?
>
> Good point.  And while a separator would be a slight nuisance to 
> express otherwise, a "suffix" isn't -- it seems to me that 
> f.writelines(x+'\n' for x in mylines) is a rather good way of 
> expressing "suffix each line with a \n".  I don't think this suffixing 
> operation is so widely more important than other elaborations on items 
> of mylines to make it worth specialcasing into a writelines argument 
> [if anything, f.writelines(str(x) for x in mylines) would be the one 
> elaboration that seems to me to be by far the most frequent -- still 
> not worth specialcasing though, IMHO].

Maybe there's a useful itertool lurking in here. I'm thinking of something
that takes a list of iterables, and generates elements from each in turn, like
a flattened izip:

    def interleave(*iterables):
	iterables = [iter(it) for it in iterables]
	while 1:
	    # Let StopIteration fall through, but make sure that
	    # each iterable generates the same number of results
	    vals = [it.next() for it in iterables]
	    for val in vals:
		yield val

Then, we're talking about

    f.writelines(interleave(mylines, repeat('\n')))

[or if you want separators rather than suffixes, use

    f.writelines(islice(interleave(repeat('\n'), mylines), 2, None))

instead]

Frankly, it's not an obvious win for the writelines case, but I was
surprised that there was nothing like interleave in itertools, and
that I couldn't find an easy way to write such a thing.

Maybe a flatten itertool would be more generally useful - 

    def flatten(iterable):
        for it in iterable:
            for val in it:
                yield val

then interleave(*iterables) is flatten(izip(*iterables))...

Thoughts? If not added as functions, would these be useful additions to
the documentation?

Paul.



More information about the Python-Dev mailing list