looping through a file

Andrew Bennetts andrew-pythonlist at puzzling.org
Wed Apr 30 19:14:54 EDT 2003


On Wed, Apr 30, 2003 at 05:12:46PM +0000, Alex Martelli wrote:
> Andrew Bennetts wrote:
>     ...
> > 
> > I thought there might be something in 2.3's itertools module to help with
> > this -- I was hoping you'd be able to write something like:
> > 
> >     InFile = open('users.dat', 'r')
> >     
> >     for username, password in multistep(InFile, 2):
> 
> Careful!!!  You'd still need to strip them before you compare them,
> else the trailing \n or any other whitespace will make the comparisons
> fail.  imap(str.strip, multistep(InFile, 2)) might work here (if
> multistep existed).

Oops!  Yes, I forgot about that.

> > Where "multistep" would probably have a better name, and be defined like:
> > 
> >     def multistep(iterable, count):
> >         # XXX: What should happen when len(iterable) % count != 0 ?
> 
> I think the last trailing part X with 0<=len(X)<count should be dropped.
> Otherwise, unpacking assigments such as the above would fail -- and,
> "padding with None's" isn't in fashion any more;-).

That's my inclination too, because it's the easiest thing to do :)

> >         iterator = iter(iterable)
> >         while 1:
> >             values = []
> >             for i in range(count):
> >                 values.append(iterator.next())
> >             yield values
> 
> I think I'd prefer expressing this loop (naming issues apart) as:
> 
>    while True: return [iterator.next() for i in range(count)]

I think you meant to use "yield", not "return".

But yes, that occurred to me after I posted :)   It's much nicer that way.

> > 
> > I couldn't see anything in itertools to save me writing that out.  But I
> > just figured out how to do it with itertools -- izip can do it:
> > 
> >     def multistep(iterable, count):
> >         return itertools.izip(*((iter(iterable),)*count))
> > 
> > I guess you could write this directly:
> > 
> >     iterator = iter(InFile)
> 
> Unneeded, btw: iter(inFile) is inFile (I also exploit that in my
> less-elegant snippet above where I call inFile.next(), secure that
> this will consume a line).

Hmm.  I couldn't remember if that was safe or not; I tested this stuff
interactively with xrange, and 

    x = xrange(10)
    print list(izip(x, x))

didn't do what I expected until I remembered to change the first line to

    x = iter(xrange(10))

So I played it safe.

> >     for username, password in izip(iterator, iterator):
> >         ...
> > 
> > So it's probably not worth defining a seperate function...
> 
> I think it is (if anything can still be added to new module itertools
> in 2.3 -- I'm not sure ANY functionality can be added after beta-1), as
> it's frequently needed.  But, if it isn't, the "trick" with the
> iterator explicitly repeated is good and IMHO worth keeping in mind.
> 
> But one does still need the .strip call...;-)

Yes :)

-Andrew.






More information about the Python-list mailing list