Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed1.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.002 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'syntax': 0.04; 'parser': 0.07; 'reason,': 0.07; 'parameter': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'python': 0.11; 'bug': 0.12; '23,': 0.16; 'distinct': 0.16; 'expression,': 0.16; 'expression.': 0.16; 'finney': 0.16; 'iterator,': 0.16; 'parentheses': 0.16; 'rather,': 0.16; 'received:80.91.229.3': 0.16; 'received:plane.gmane.org': 0.16; 'there?': 0.16; 'wrote:': 0.18; 'header:User-Agent:1': 0.23; 'typical': 0.24; 'performing': 0.26; 'header:X-Complaints-To:1': 0.27; '[1]': 0.29; 'am,': 0.29; 'dec': 0.30; 'needed.': 0.30; 'commonly': 0.31; 'subject:learning': 0.31; 'writes:': 0.31; 'used,': 0.33; 'role': 0.34; 'knows': 0.35; 'but': 0.35; 'words,': 0.36; 'similar': 0.36; 'list': 0.37; 'list.': 0.37; 'clear': 0.37; 'ben': 0.38; 'needed': 0.38; 'to:addr:python-list': 0.38; 'rather': 0.38; 'to:addr:python.org': 0.39; 'received:org': 0.40; 'expression': 0.60; 'ian': 0.60; 'affect': 0.61; 'advanced': 0.63; 'such': 0.63; 'skip:\xe2 10': 0.65; 'surrounding': 0.68; 'ambiguous': 0.84; 'of*': 0.84; 'received:125': 0.84 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Ben Finney Subject: Re: learning to use iterators Date: Wed, 24 Dec 2014 08:25:45 +1100 References: <878uhyb3hq.fsf@net82.ceos.umanitoba.ca> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Gmane-NNTP-Posting-Host: jigong.madmonks.org X-Public-Key-ID: 0xAC128405 X-Public-Key-Fingerprint: 517C F14B B2F3 98B0 CB35 4855 B8B2 4C06 AC12 8405 X-Public-Key-URL: http://www.benfinney.id.au/contact/bfinney-pubkey.asc X-Post-From: Ben Finney User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) Cancel-Lock: sha1:eDzGl+HtLpaHNDC+oKeNKSZtDEA= X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 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: 40 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1419369959 news.xs4all.nl 2927 [2001:888:2000:d::a6]:45919 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:82857 Ian Kelly writes: > On Tue, Dec 23, 2014 at 11:55 AM, Seb wrote: > > Particulary, what do the parentheses do there? > > The parentheses enclose a generator expression, which is similar to a > list comprehension [1] but produce a generator, which is a type of > iterator, rather than a list. To be clear: there's nothing about parentheses that produce a generator expression. Rather, parentheses are just performing their typical role of enclosing an expression. The generator expression is produced by the syntax used, such as ‘frob(spam) for spam in collection_of_spam if spam > 0’. The surrounding parentheses don't affect that; they are not part of the generator syntax. They *do* enclose it so the Python parser knows it is an expression distinct from what surrounds it. For this reason, if you already have some syntax where it will be clear what is a distinct expression, additional parentheses are not needed. In other words, parentheses are only needed to *separate* a generator expression from its surrounds. # Syntax would be ambiguous without parentheses. foo = (frob(spam) for spam in collection_of_spams if spam > 0) # Syntax already dictates the parameter is an expression; # no additional parens needed. twiddle(frob(spam) for spam in collection_of_spams if spam > 0) Parens are used in a lot of places, but they are commonly not *part of* the expression; rather, they enclose the expression to be unambiguous. -- \ “Any sufficiently advanced bug is indistinguishable from a | `\ feature.” —Rich Kulawiec | _o__) | Ben Finney