[Python-ideas] "While" suggestion

Terry Reedy tjreedy at udel.edu
Wed Jul 30 17:00:46 CEST 2008



Steven Bethard wrote:
> On Tue, Jul 29, 2008 at 8:55 PM, Terry Reedy <tjreedy at udel.edu> wrote:
>> Steven Bethard wrote:
>>> On Tue, Jul 29, 2008 at 3:19 PM, Terry Reedy <tjreedy at udel.edu> wrote:
>>>> Roman Susi wrote:
>>>>> Python already has dict/list literals + list comprehensions.

I could have mentioned here that Python does not have dict or list 
*literals*.  It only have number and string/bytes literals.  It has set, 
dict, and list *displays*.  One form of display content is a sequence of 
expressions, a tuple list (with a special form for dicts).  Another form 
of display content is a genexp (with a special form for dict 
comprehensions).

>>>> Better to think that Python has generator expressions which can be used
>>>> in list, set, and dict comprehensions (the latter two in 3.0 and maybe 2.6).

The above is a slightly better way to say this.

>>> You probably don't want to think about it that way - a list/set/dict
>>> comprehension does not actually create a generator.

I never said it necessarily did.  The fact that [tuple_list] == 
list((tuple_list)) does not mean that [tuple_list] actually creates a 
tuple object.  An interpreter could, but CPython does not.  Similarly, 
f(1,2,3) could create a tuple object, but CPython does not.



>> Yes I do.  For normal purposes, in 3.0, [genexp] == list(genexp), and so on.
>>  That it do something else internally for efficiency is implementation
>> detail, not semantics.
> 
> But the semantics are pretty different.

I never said that listcomp == genexp, I said that listcomp 
(setcomp,dictcomp) == bracketed genexp == list/set/dict(genexp)

  The semantics are basically:
> 
>     def _(seq):
>         _1 = []
>         for x in seq:
>             _1.append(<expression with x>)
>         return _1
>     return _(seq)
> 
>     def _(seq):
>         for x in seq:
>             yield <expression with x>
>     return list(_(seq))
> 
> Yes, they produce the same results,

The results of the expressions are their semantics.  When you write 547 
+ 222, the semantics is the result 769, not the internal implementation 
of how a particular interpreter arrives at that.  Anyway, in Python, 
'==' is value comparison, not algorithm comparison.

> but semantically they're
> different. In one case, a list is created and items are appended to it
> and then that list is returned. In the other case, a generator object
> is created, and then that generator is repeatedly resumed to yield
> items by the list() constructor.

This is a CPython internal implementation choice.  In each case, a list 
object is created and items appended to it.  The internal question is 
how the objects are generated.  The list(genexp) implementation was 
considered until the faster version was created.  [genexp] == 
list(genexp) was the design goal.  I said 'for normal purposes' because 
it turns out that the the faster implementation allows that equality to 
be broken with somewhat bizarre and abusive code that should never 
appear in practical code.  The developers tried to fix this minor glitch 
but could not without reverting to the slower list(genexp) version, so 
they decided to leave things alone.

My point is that if one understands genexp, one really understands the 
comprehensions also.  It is a matter of reducing cognitive load.  I 
happen to be in favor of that.

Terry Jan Reedy




More information about the Python-ideas mailing list