On 24 March 2018 at 23:29, Christoph Groth <christ...@grothesque.org> wrote:

>
> x = [n * m for n in range(4) for m in range(5)]
>
> be equally well equivalent to
>
> def <listcomp>():
>     ret = []
>     for n in range(4):
>         for m in range(5):
>             ret.append(n * m)
>     return ret
> x = <listcomp>()
>
> As far as I can tell, with today's Python both implementations (yours
> and mine) are indistinguishable by the user.
>

They can be distinguished, just not at module or function scope. To give a
concrete example:

==========
    >>> class C:
    ...     sequence = range(10)
    ...     listcomp = [x for x in sequence]
    ...     def works(data):
    ...         return list(data)
    ...     from_works = works(sequence)
    ...     def fails():
    ...         return list(sequence)
    ...
    >>> C.listcomp
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> C.from_works
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> C.fails()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 8, in fails
    NameError: name 'sequence' is not defined
==========

I think I did have an implementation that didn't do the "outermost iterator
is evaluated in the outer scope" dance early on (back when I was still
working on the initial version of the iteration variable hiding, before it
was merged to the Py3k branch), but quickly changed it because relying
solely on closures broke too much code (in addition to the class namespace
case, you can create a situation with similar constraints by passing a
separate locals namespace to exec).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to