Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; '---------': 0.05; 'behavior,': 0.09; 'filter,': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'subject:iterable': 0.09; 'terry': 0.09; 'programmer': 0.11; 'subject:not': 0.11; '(x,': 0.16; 'attributes,': 0.16; 'exhausted': 0.16; 'iterable': 0.16; 'iterator': 0.16; 'message-id:@dough.gmane.org': 0.16; 'rationale': 0.16; 'received:80.91.229.3': 0.16; 'received:plane.gmane.org': 0.16; 'reedy': 0.16; 'reproducing': 0.16; 'subject:object': 0.16; 'subject:when': 0.16; 'wrote:': 0.17; 'jan': 0.18; 'tim': 0.18; '>>>': 0.18; 'memory': 0.18; 'latter': 0.22; 'produces': 0.22; "i'd": 0.22; 'nearly': 0.23; 'seems': 0.23; 'external': 0.24; 'header:In-Reply-To:1': 0.25; 'header:User-Agent:1': 0.26; 'guess': 0.27; 'first.': 0.27; 'header:X-Complaints-To:1': 0.28; 'chase': 0.29; 'forces': 0.29; 'once,': 0.29; 'objects': 0.29; 'print': 0.32; 'to:addr:python- list': 0.33; 'produced': 0.33; "can't": 0.34; 'filter': 0.35; 'saved': 0.35; 'pm,': 0.35; 'similar': 0.35; 'received:org': 0.36; 'but': 0.36; 'compare': 0.36; 'depends': 0.36; 'should': 0.36; 'two': 0.37; 'being': 0.37; 'data': 0.37; 'subject:: ': 0.38; 'object': 0.38; 'speak': 0.38; 'some': 0.38; 'to:addr:python.org': 0.39; 'list,': 0.39; 'header:Received:5': 0.40; 'range': 0.60; 'save': 0.61; 'different': 0.63; 'more': 0.63; 'behavior': 0.64; 'counts': 0.81; '$$$': 0.84; '(your': 0.84; 'filtered': 0.84; 'received:fios.verizon.net': 0.84; 'demand.': 0.91; 'hand,': 0.97 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Terry Reedy Subject: Re: when an iterable object is exhausted or not Date: Sat, 04 Aug 2012 17:04:51 -0400 References: <501D84E2.6000404@tim.thechases.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Gmane-NNTP-Posting-Host: pool-173-75-251-66.phlapa.fios.verizon.net User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20120713 Thunderbird/14.0 In-Reply-To: <501D84E2.6000404@tim.thechases.com> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 55 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1344114320 news.xs4all.nl 6903 [2001:888:2000:d::a6]:48432 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:26509 On 8/4/2012 4:24 PM, Tim Chase wrote: > On 08/04/12 14:20, Franck Ditter wrote: >> Two similar iterable objects but with a different behavior : >> >> $$$ i = range(2,5) >> $$$ for x in i : print(x,end=' ') >> >> 2 3 4 >> $$$ for x in i : print(x,end=' ') # i is not exhausted >> >> 2 3 4 >> >> --------- Compare with : >> >> $$$ i = filter(lambda c : c.isdigit(), 'a1b2c3') >> $$$ for x in i : print(x,end=' ') >> >> 1 2 3 >> $$$ for x in i : print(x,end=' ') # i is exhausted >> >> $$$ >> >> IMHO, this should not happen in Py3k. >> What is the rationale of this (bad ?) design, which forces the programmer >> to memorize which one is exhaustable and which one is not ?... > > I can't speak to the rationale, but it seems that a range() object > has some extra features that a normal iter doesn't: > > >>> i = iter(range(2,5)) > >>> for x in i: print (x, end=' ') > ... > 2 3 4 >>> for x in i: print (x, end=' ') > ... > > (your 2nd behavior, and what I'd expect). > > So my guess would be that the "for {var} in {thing}" triggers a > re-calling of range.__iter__ since it's not an iterator to begin with. range produces a re-iterable range object because it can. The result is self-contained with 3 data attributes, so it can create rangeiterators on demand. filter, on the other hand, depends on an external iterable and it cannot depend on that external object being re-iterable. So even if we programmed filter() to produce a filter object that produced filteriterators, the latter would often only work for the first. Also, If you want the filtered collection more than once, you should just save it. On the other hand, reproducing counts with a rangeiterator is nearly as fast as looking them up in a saved list, and much more memory efficient. -- Terry Jan Reedy