Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Erik Newsgroups: comp.lang.python Subject: Re: Help on for loop understanding Date: Tue, 8 Dec 2015 02:36:00 +0000 Lines: 80 Message-ID: References: <5d02c61f-a979-4121-a9ae-764b44903156@googlegroups.com> <4f64bcda-15f2-4c6f-a279-b76330fb7f39@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de GiyvB8RcUV8ZoeypA3W5hw2hT1EYi4aD9MCnsyXxl8MQ== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; '(python': 0.05; '"__main__":': 0.07; '__name__': 0.07; 'raises': 0.07; 'backwards': 0.09; 'iterate': 0.09; 'lst': 0.09; "object's": 0.09; 'subclass': 0.09; 'subclasses': 0.09; 'subject:Help': 0.10; 'python': 0.10; 'def': 0.13; '"for"': 0.16; "%r'": 0.16; '2):': 0.16; 'exited.': 0.16; 'from:addr:python': 0.16; 'iterator': 0.16; 'iterator,': 0.16; 'iterator.': 0.16; 'received:84.93': 0.16; 'received:84.93.230': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'returned,': 0.16; 'true:': 0.16; 'wrote:': 0.16; 'element': 0.18; 'example.': 0.18; 'implementing': 0.18; 'tells': 0.18; 'versions': 0.20; 'first,': 0.20; 'posted': 0.21; 'to:2**1': 0.21; 'trying': 0.22; 'defined': 0.23; '(you': 0.23; 'second': 0.24; 'header:In-Reply-To:1': 0.24; 'script': 0.25; 'header:User-Agent:1': 0.26; "doesn't": 0.26; 'example': 0.26; '(which': 0.26; 'sense': 0.26; 'followed': 0.27; '(such': 0.27; 'correct': 0.28; 'this.': 0.28; 'behaviour': 0.29; 'loop,': 0.29; 'second,': 0.29; 'subject:skip:u 10': 0.29; 'raise': 0.29; 'print': 0.30; 'classes': 0.30; 'code': 0.30; 'especially': 0.32; 'skip:_ 10': 0.32; 'says': 0.32; 'embedded': 0.32; 'received:84': 0.32; 'returned': 0.32; 'class': 0.33; 'instead,': 0.33; 'skip:- 10': 0.34; 'case,': 0.34; 'me?': 0.34; 'list': 0.34; 'so,': 0.35; 'robert': 0.35; 'quite': 0.35; 'something': 0.35; 'comment': 0.35; 'item': 0.35; 'skip:i 20': 0.36; 'should': 0.36; 'there': 0.36; "wasn't": 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'two': 0.37; 'method': 0.37; 'link.': 0.37; 'list.': 0.37; 'things': 0.38; 'version': 0.38; 'self': 0.38; 'anything': 0.38; 'someone': 0.38; 'why': 0.39; 'does': 0.39; 'received:192': 0.39; 'to:addr:python.org': 0.40; 'your': 0.60; 'default': 0.61; 'telling': 0.61; 'charset:windows-1252': 0.62; 'please,': 0.63; 'more': 0.63; 'it!': 0.64; 'delegate': 0.66; 'inherit': 0.66; 'here': 0.66; 'results.': 0.67; "class's": 0.84; '"how': 0.91; 'you).': 0.95 X-CM-Score: 0.00 X-CNFS-Analysis: v=2.1 cv=JN/GyJ+b c=1 sm=1 tr=0 a=Ypmeq7T0cKALDUsRPCToMg==:117 a=Ypmeq7T0cKALDUsRPCToMg==:17 a=0Bzu9jTXAAAA:8 a=EBOSESyhAAAA:8 a=N659UExz7-8A:10 a=Q1kXPCNhSsMMihRm6bcA:9 a=pILNOxqGKmIA:10 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 In-Reply-To: <4f64bcda-15f2-4c6f-a279-b76330fb7f39@googlegroups.com> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:100129 On 08/12/15 01:50, Robert wrote: > One example, see below please, is in the above mentioned link. I don't see > the purpose of the example. OK, so there are two parts to this. The first, is "how do I iterate over something". The answer to that is using "for" or using "iter()" followed by zero or more calls to "next()". In this case, by using the correct syntax/function calls your script can work under various versions of Python without change. The second is "how do I make my own classes iterable". This is what the example you pasted is trying to show. In this case, you are implementing things which are "internal" to the way the version of Python you are using does things (which is why the code Robin posted wasn't quite right for you). > I have the following two same results. What do they tell me? They tell you that the implementation does the same thing as the default implementation for a list. That perhaps doesn't help much - especially with the comment in the example telling you not to do it! Instead, try the following (Python 2): class MyList(list): def __iter__(self): return MyListIter(self) class MyListIter(object): def __init__(self, lst): self.lst = lst self.i = -1 def __iter__(self): return self def next(self): if self.i >= -len(self.lst): item = self.lst[self.i] self.i -= 1 return item raise StopIteration if __name__ == "__main__": a = MyList([1, 2, 3, 4]) ia = iter(a) print 'type(a): %r, type(ia): %r' %(type(a), type(ia)) for i in a: print i, print while True: print next(ia) What we have here is the same class that subclasses 'list'. It's just a list. However, it has a custom iterator. In this implementation the iterator works BACKWARDS through the list - the final element is returned first, the penultimate element second, and so on. After the first element has been returned, the iterator raises StopIteration. This tells you not to call next() again, or if in a for loop, the loop is exited. So, you can write your class's iterator to do anything that makes sense when someone says "for i in myclassinstance:". If your class is a subclass of a class ("is-a") that already has a defined iterator (such as a list or a dict) and the behaviour of that is correct for you, then you need to do nothing (you inherit that class's __iter__() method). If your class should iterate over an embedded object ("has-a") that already has a defined iterator, then your __iter__() method can just delegate to that object's iterator using something like: def __iter__(self): return iter(self.embedded_thing) Does that make more sense? E.