Screwing Up looping in Generator
Deborah Swanson
python at deborahswanson.net
Tue Jan 3 16:19:17 EST 2017
> > > Sayth Renshaw wrote, on January 03, 2017 6:54 AM
> > > >
> > > > Hi
> > > >
> > > > This is simple, but its getting me confused.
> > > >
> > > > I have a csv writer that opens a file and loops each line of the
> > > > file for each file and then closes, writing one file.
> > > >
> > > > I want to alter the behaviour to be a written file for
> each input
> > > > file. I saw a roundrobin example however it failed for
> me as you
> > > > cannot get len(generator) to use a while loop on. it exhausts
> > > >
> > > > should I use the same for again after the with open?
> > > >
> > > > rootobs in this code is my generator and I am already looping it
> > > > however def data_attr(roots):
> > > > """Get the root object and iter items."""
> > > > for file in rootobs:
> > > > base = os.path.basename(file.name)
> > > > write_to = os.path.join("output",
> > > > os.path.splitext(base)[0] + ".csv")
> > > > with open(write_to, 'w', newline='') as csvf:
> > > > race_writer = csv.writer(csvf, delimiter=',')
> > > > race_writer.writerow(
> > > > ["meet_id", "meet_venue", "meet_date",
> > "meet_rail",
> > > > ...
> > > > # other categories here
> > > > ...
> > > > "jockeysurname", "jockeyfirstname"])
> > > > for xml_data in roots:
> > > > ...
> > > > # parsing code
> > > > for noms in race_child:
> > > > if noms.tag == 'nomination':
> > > > race_writer.writerow(
> > > > [meet_id, meet_venue,
> > meet_date,
> > > > ...
> > > > #parsing info removed
> > > >
> > > noms.get("jockeyfirstname")])
> > > >
> > > > Cheers
> > > > Sayth
> > >
> > > What's the code for your generator? And I don't see where
> you call
> > > 'next'.
> >
> > I think you're expecting
> >
> > for file in rootobs
> >
> > to get the next yield for you from rootobs, but unless
> > someone corrects me, I don't think you can expect a 'for'
> > statement to do that. You need to have a 'next' statement
> > inside your for loop to get the next yield from the generator.
> >
> > But I might not understand exactly what you're asking.
>
> You probably want something like :
>
> for f in rootobs:
> file = next
> base = os.path.basename(file.name)
> .
> .
> .
> (etc)
>
> Notice I changed your iterating variable name to 'f', so you
> can use 'file' throughout your code after you get the next
> one from rootobs.
>
> As written, you'll get a StopIteration exception when rootobs
> runs out of files, which you can catch with a try/except. Or
> you can just let the code end there if you're done.
Well rats, I'm embarrassed. It's been awhile since I've used a generator
and I forgot that you have to create the generator object first and use
it to call the next function. And I really don't think you can use a
generator as your range in a for loop. So I'd use a 'while True', and
break out of the loop when you hit the StopIteration exception:
files = rootobs()
while True:
try:
file = files.next()
except StopIteration:
break
base = os.path.basename(file.name)
.
.
.
(etc)
(Now I'm just going to shut up, until somebody else says something.)
More information about the Python-list
mailing list