Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed4a.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.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'subject:Python': 0.06; '21,': 0.07; 'nested': 0.07; '[1,': 0.09; 'false.': 0.09; 'happen.': 0.09; 'raises': 0.09; 'separately': 0.09; 'subject:language': 0.09; 'variable,': 0.09; 'runs': 0.10; 'stored': 0.12; '2],': 0.16; 'before.': 0.16; 'evaluates': 0.16; 'initially,': 0.16; 'introduces': 0.16; 'iterated': 0.16; 'iterator': 0.16; 'loop.': 0.16; 'once.': 0.16; 'scopes': 0.16; 'subject: \n ': 0.16; 'variable.': 0.16; 'wrote:': 0.18; 'variable': 0.18; '>>>': 0.22; 'code,': 0.22; 'example': 0.22; 'print': 0.22; 'holds': 0.26; 'header:In-Reply-To:1': 0.27; 'subject:list': 0.30; 'message-id:@mail.gmail.com': 0.30; '>>>>': 0.31; 'yields': 0.31; 'fri,': 0.33; 'received:google.com': 0.35; 'there': 0.35; 'really': 0.36; 'next': 0.36; 'list.': 0.37; 'expected': 0.38; 'needed': 0.38; 'to:addr:python-list': 0.38; 'fact': 0.38; 'pm,': 0.38; 'to:addr:python.org': 0.39; 'read': 0.60; 'expression': 0.60; 'hope': 0.61; 'first': 0.61; 'real': 0.63; 'here': 0.66; 'mar': 0.68; 'subject:this': 0.83; "'for'": 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=SDkDvkZiFq/FUUcJAHCMoMCI5jdgY1z4XeqWjWCZg/g=; b=h0kd6ADM0mCYkDQ+oRGopEKemydeUXId9783+hB7Zr67jL2rPh2Wd8Ym5DYJOrJjC0 s7AbQsdsmxq3m0W9rT9pQec1VNCxYTEhioczapq4Yx9MZrfb6PPlXsb1mbPd7aLqx4rI YLWkKVtw1LwSIk8KRefo+Y5ajgSAmdizoNIPh2TCSsmblxvq2IyA12Iq0OkNdmDPlJ5H gmYgWZHHrEJOqJM/LZHLIFTTKWsGjPWSPCwLHZpr2+r+s3WyYUqWSOsQiqF6YG0uL3Ke 0Vmj+VEo4k8Z7EKBMefYvkcPDO/Z3+a/FE6uGa6VwZjzFNUUucW1+vjgD6bekIygpRHr 2l7A== X-Received: by 10.66.151.205 with SMTP id us13mr56384251pab.93.1395437451072; Fri, 21 Mar 2014 14:30:51 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: <9daf0806-02de-4447-964c-c8f8953c23e5@googlegroups.com> <10101874-2995-4acd-9851-989603f052e3@googlegroups.com> From: Ian Kelly Date: Fri, 21 Mar 2014 15:30:10 -0600 Subject: Re: Explanation of this Python language feature? [x for x in x for x in x] (to flatten a nested list) To: Python Content-Type: text/plain; charset=ISO-8859-1 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: 69 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1395437459 news.xs4all.nl 2975 [2001:888:2000:d::a6]:34897 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:68715 On Fri, Mar 21, 2014 at 3:09 PM, Rustom Mody wrote: > A 'for' introduces a scope: This is false. >>>> x = 42 >>>> for x in [1,2,3]: > ... print x > ... > 1 > 2 > 3 > > No sign of the 42 --v ie the outer x -- inside because of scope Try printing x again *after* the for loop: >>> x = 42 >>> for x in [1,2,3]: ... print(x) ... 1 2 3 >>> print(x) 3 Notice that it's still 3. If the x in the for loop were really a separately scoped variable, we would have expected to see 42 here. In fact the x used in the for loop and the x used outside of it are the same x variable. The real reason that the OP's example works is because each value that the x variable holds happens to only need to be read once. Start with this code, and work through it line-by-line: x = [[1, 2], [3, 4]] for x in x: for x in x: print(x) Initially, x is assigned the list. Then we enter the outer for loop. The expression x is evaluated once to be iterated over. The first value that the for loop iterator yields is [1, 2], which is then assigned to x. Now we enter the inner for loop. The expression x is again evaluated once to be iterated over. It first yields 1, which is assigned to x, and then printed. The inner for loop iterator then yields 2, which is also assigned to x and printed. The inner for loop iterator then raises StopIteration, and the inner for loop terminates. The outer for loop iterator then yields [3, 4], and this is assigned to x. The inner for loop evaluates this expression and runs as before. Afterward, the outer for loop iterator raises StopException, and that for loop terminates. The final value of x here will be 4: >>> x = [[1, 2], [3, 4]] >>> for x in x: ... for x in x: ... print(x) ... 1 2 3 4 >>> print(x) 4 As I hope this makes clear, no nested scopes are needed to make this happen. It works because nothing that is stored in x needs to remain there after the next thing is stored in x.