473,472 Members | 1,856 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

How to stop iteration with __iter__() ?

I want a parse a file of the format:
movieId
customerid, grade, date
customerid, grade, date
customerid, grade, date
etc.

so I could do with open file as reviews and then for line in reviews.

but first I want to take out the movie id so I use an iterator.

then i want to iterate through all the rows, but how can I do:
while movie_iter != None:

because that doesn't work, itraises an exception, StopItreation, which
according to the documentation it should. But catching an exception
can't be the standard way to stop iterating right?
Aug 19 '08 #1
10 3317
On Aug 19, 7:39*am, ssecorp <circularf...@gmail.comwrote:
I want a parse a file of the format:
movieId
customerid, grade, date
customerid, grade, date
customerid, grade, date
etc.

so I could do with open file as reviews and then for line in reviews.

but first I want to take out the movie id so I use an iterator.

then i want to iterate through all the rows, but how can I do:
while movie_iter != None:

because that doesn't work, itraises an exception, StopItreation, which
according to the documentation it should. But catching an exception
can't be the standard way to stop iterating right?
No. If you are defining the iterator, then the iterator raises
StopIteration when it is complete. It is not an exception you
normally catch; you use a for loop to iterate, and the machinery of
the for loop uses the StopIteration exception to tell it when to
break. A file-like object is itself a line iterator, so:

def review_iter(file_obj):
for line in file_obj:
if matches_some_pattern(line):
yield line

Then, to use it:

file_obj = open('/path/to/some/file.txt')
try:
for review in review_iter(file_obj):
do_something(review)
finally:
file_obj.close()
Aug 19 '08 #2
On Aug 19, 12:39 pm, ssecorp <circularf...@gmail.comwrote:
I want a parse a file of the format:
movieId
customerid, grade, date
customerid, grade, date
customerid, grade, date
etc.

so I could do with open file as reviews and then for line in reviews.

but first I want to take out the movie id so I use an iterator.

then i want to iterate through all the rows, but how can I do:
while movie_iter != None:

because that doesn't work, itraises an exception, StopItreation, which
according to the documentation it should. But catching an exception
can't be the standard way to stop iterating right?
Given your example, why not just open the file and call .next() on it
to discard the first row, then iterate using for as usual?

hth
Jon
Aug 19 '08 #3
On Tue, Aug 19, 2008 at 7:39 PM, ssecorp <ci**********@gmail.comwrote:
I want a parse a file of the format:
movieId
customerid, grade, date
customerid, grade, date
customerid, grade, date
etc.

so I could do with open file as reviews and then for line in reviews.

but first I want to take out the movie id so I use an iterator.

then i want to iterate through all the rows, but how can I do:
while movie_iter != None:

because that doesn't work, itraises an exception, StopItreation, which
according to the documentation it should. But catching an exception
can't be the standard way to stop iterating right?
you can use for loop:
for line in movie_iter:
...

--
Best Regards,
Leo Jay
Aug 19 '08 #4


ssecorp wrote:
I want a parse a file of the format:
movieId
customerid, grade, date
customerid, grade, date
customerid, grade, date
etc.

so I could do with open file as reviews and then for line in reviews.

but first I want to take out the movie id so I use an iterator.

then i want to iterate through all the rows, but how can I do:
while movie_iter != None:

because that doesn't work, itraises an exception, StopItreation, which
according to the documentation it should. But catching an exception
can't be the standard way to stop iterating right?
Catching StopIteration *is* the usual way to stop iterating with an
iterator. Using while, one must be explicit:

it = iter(iterable)
try:
while True:
item = next(iter) # 2.6,3.0
f(item)
except StopIteration:
pass

but the main reason to write the above is to show the advantage of
simply writing the equivalent (and implicit)

for item in iterable:
f(item)

;-)

In your case, the standard Python idiom, as Jon said, is

it = iter(iterable)
next(it) # 2.6, 3.0
for for item in iterable:
f(item)

The alternative is a flag variable and test

first = True
for for item in iterable:
if first:
first = False
else:
f(item)

This takes two more lines and does an unnecessary test for every line
after the first. But this approach might be useful if, for instance,
you needed to skip every other line (put 'first = True' after f(item)).

Terry Jan Reedy

Aug 19 '08 #5
On Aug 20, 5:06 am, Terry Reedy <tjre...@udel.eduwrote:
In your case, the standard Python idiom, as Jon said, is

it = iter(iterable)
next(it) # 2.6, 3.0
for for item in iterable:
f(item)
or, perhaps, for completeness/paranoia/whatever:

it = iter(iterable)
try:
headings = it.next() # < 2.5
except StopIteration:
# code to handle empty <iterable>
for item etc etc
The alternative is a flag variable and test

first = True
for for item in iterable:
if first:
first = False
else:
f(item)

This takes two more lines and does an unnecessary test for every line
after the first. But this approach might be useful if, for instance,
you needed to skip every other line (put 'first = True' after f(item)).
and change its name from 'first' to something more meaningful ;-)

Cheers,
John
Aug 19 '08 #6
On Aug 20, 12:11*am, John Machin <sjmac...@lexicon.netwrote:
On Aug 20, 5:06 am, Terry Reedy <tjre...@udel.eduwrote:
In your case, the standard Python idiom, as Jon said, is
it = iter(iterable)
next(it) # 2.6, 3.0
for for item in iterable:
* *f(item)

or, perhaps, for completeness/paranoia/whatever:

it = iter(iterable)
try:
* *headings = it.next() # < 2.5
except StopIteration:
* *# code to handle empty <iterable>
for item etc etc
I think it needs to be:

it = iter(iterable)
try:
headings = it.next() # < 2.5
except StopIteration:
# code to handle empty <iterable>
else:
for item etc etc

because you don't want to iterate over the remainder if it has already
stopped yielding! :-)
The alternative is a flag variable and test
first = True
for for item in iterable:
* *if first:
* * *first = False
* *else:
* * *f(item)
This takes two more lines and does an unnecessary test for every line
after the first. *But this approach might be useful if, for instance,
you needed to skip every other line (put 'first = True' after f(item)).

and change its name from 'first' to something more meaningful ;-)

Cheers,
John
Aug 20 '08 #7
On Aug 20, 7:56*pm, MRAB <goo...@mrabarnett.plus.comwrote:
On Aug 20, 12:11*am, John Machin <sjmac...@lexicon.netwrote:
or, perhaps, for completeness/paranoia/whatever:
it = iter(iterable)
try:
* *headings = it.next() # < 2.5
except StopIteration:
* *# code to handle empty <iterable>
for item etc etc

I think it needs to be:

it = iter(iterable)
try:
* * headings = it.next() # < 2.5
except StopIteration:
* * # code to handle empty <iterable>
else:
* * for item etc etc

because you don't want to iterate over the remainder if it has already
stopped yielding! :-)
If it has stopped yielding, the remainder is nothing/null/empty, isn't
it?
In any case "code to handle empty <iterable>" is likely to end with a
raise or return statement.

Cheers,
John
Aug 20 '08 #8
On Aug 20, 11:27*am, John Machin <sjmac...@lexicon.netwrote:
On Aug 20, 7:56*pm, MRAB <goo...@mrabarnett.plus.comwrote:
On Aug 20, 12:11*am, John Machin <sjmac...@lexicon.netwrote:
or, perhaps, for completeness/paranoia/whatever:
it = iter(iterable)
try:
* *headings = it.next() # < 2.5
except StopIteration:
* *# code to handle empty <iterable>
for item etc etc
I think it needs to be:
it = iter(iterable)
try:
* * headings = it.next() # < 2.5
except StopIteration:
* * # code to handle empty <iterable>
else:
* * for item etc etc
because you don't want to iterate over the remainder if it has already
stopped yielding! :-)

If it has stopped yielding, the remainder is nothing/null/empty, isn't
it?
In any case "code to handle empty <iterable>" is likely to end with a
raise or return statement.
So it's defined behaviour that an exhausted iterable will always raise
StopIteration no matter how many times it's asked for the next value?
Aug 20 '08 #9
MRAB wrote:
So it's defined behaviour that an exhausted iterable will always raise
StopIteration no matter how many times it's asked for the next value?
That is not enforced. However, quoting
http://www.python.org/dev/peps/pep-0234/

"""
Iterator implementations (in C or in Python) should guarantee that
once the iterator has signalled its exhaustion, subsequent calls
to tp_iternext or to the next() method will continue to do so.
"""

Peter
Aug 20 '08 #10
On Wed, 20 Aug 2008 06:16:17 -0700, MRAB wrote:
So it's defined behaviour that an exhausted iterable will always raise
StopIteration no matter how many times it's asked for the next value?
Be careful -- an iterable is not the same as an iterator.

Iterables are anything that you can iterate over. This includes strings,
lists, tuples, dicts and, yes, iterators.

But not all iterables are iterators. Only iterators raise StopIteration.
The defined behaviour of iterators is that once exhausted, they will
always raise StopIteration.

Basically, Python will do the right thing in a for loop regardless of
whether you pass an iterator or some other type of iterable. You don't
have to worry about the mechanics of it, but if you care, it works
something like this:

When Python executes a for-loop:

for item in obj:
BLOCK

it does something kind of like this:
if hasattr(obj, "next"):
# Looks like an iterator.
while True:
try:
item = obj.next()
except StopIteration:
break
execute BLOCK
elif hasattr(obj, "__getitem__"):
# Looks like a string, or list, or similar.
i = 0
while True:
try:
item = obj[i]
except IndexError:
break
execute BLOCK
i += 1
else:
raise TypeError('object not iterable')

--
Steven
Aug 20 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Franck Bui-Huu | last post by:
Hello, I'm trying to customize a list by overriding __getitem__ method but this change seems to not work with for iteration. When I use my customized list in a for iteration, all changes made...
5
by: Philippe Rousselot | last post by:
Hi, How do I find the second iteration of a character in a string using python this gives me the first one f1 = string.find(line,sub) this the last one f2 = string.rfind(line,sub)
35
by: Raymond Hettinger | last post by:
Here is a discussion draft of a potential PEP. The ideas grew out of the discussion on pep-284. Comments are invited. Dart throwing is optional. Raymond Hettinger ...
59
by: Raymond Hettinger | last post by:
Please comment on the new PEP for reverse iteration methods. Basically, the idea looks like this: for i in xrange(10).iter_backwards(): # 9,8,7,6,5,4,3,2,1,0 <do something with i> The...
31
by: Raymond Hettinger | last post by:
Based on your extensive feedback, PEP 322 has been completely revised. The response was strongly positive, but almost everyone preferred having a function instead of multiple object methods. The...
14
by: Raymond Hettinger | last post by:
Based on the feedback here on comp.lang.python, the pep has been updated: www.python.org/peps/pep-0322.html The key changes are: * reversed() is being preferred to ireverse() as the best...
21
by: Steven Bethard | last post by:
Can someone point me to the documentation on what's supposed to happen when you use the "for x in X:" syntax when X does not have an __iter__ method? I know that the code: >>> class S: .... ...
8
by: Steven Bethard | last post by:
Sorry if this is a repost -- it didn't appear for me the first time. So I was looking at the Language Reference's discussion about emulating container types, and nowhere in it does it mention...
13
by: Thomas Heller | last post by:
I'm trying to implement __iter__ on an abstract base class while I don't know whether subclasses support that or not. Hope that makes sense, if not, this code should be clearer: class Base: def...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.