Friday Finking: initialising values and implied tuples

Rob Cliffe rob.cliffe at btinternet.com
Mon Apr 5 12:20:13 EDT 2021



On 05/04/2021 00:47, dn via Python-list wrote:
> On 04/04/2021 01.00, Rob Cliffe via Python-list wrote:
>>
>> On 03/04/2021 04:09, 2QdxY4RzWzUUiLuE at potatochowder.com wrote:
>>> On 2021-04-03 at 02:41:59 +0100,
>>> Rob Cliffe via Python-list <python-list at python.org> wrote:
>>>
>>>>       x1 = 42; y1 =  3;  z1 = 10
>>>>       x2 = 41; y2 = 12; z2 = 9
>>>>       x3 =  8;  y3 =  8;  z3 = 10
>>>> (please imagine it's in a fixed font with everything neatly vertically
>>>> aligned).
>>>> This has see-at-a-glance STRUCTURE: the letters are aligned vertically
>>>> and the "subscripts" horizontally.  Write it as 9 lines and it becomes
>>>> an amorphous mess in which mistakes are harder to spot.
>>> I agree that writing it as 9 lines is an accident waiting to happen, but
>>> if you must see that structure, then go all in:
>>>
>>>       (x1, y1, z1) = (43,  3, 10)
>>>       (x2, y2, z2) = (41, 12,  9)
>>>       (x3, y3, z3) = ( 8,  8, 10)
>> Agreed, that is even easier to read.  (It would be kinda nice if the
>> compiler could optimise the tuples away, for those of us who are
>> paranoid about performance.)
> I think I've read that the compiler is smart-enough to realise that the
> RHS 'literal-tuples'?'tuple-literals' are being used as a 'mechanism',
> and thus the inits are in-lined. Apologies: I can't find a web.ref.
> Likely one of our colleagues, who is 'into' Python-internals, could
> quickly clarify...
> [snip]
It doesn't appear to, at least not always.  In Python 3.8.3:
from dis import dis
def f(): x = 1 ; y = 2
def g(): (x,y) = (1,2)
dis(f)
dis(g)

Output:
   2           0 LOAD_CONST               1 (1)
               2 STORE_FAST               0 (x)
               4 LOAD_CONST               2 (2)
               6 STORE_FAST               1 (y)
               8 LOAD_CONST               0 (None)
              10 RETURN_VALUE
   3           0 LOAD_CONST               1 ((1, 2))
               2 UNPACK_SEQUENCE          2
               4 STORE_FAST               0 (x)
               6 STORE_FAST               1 (y)
               8 LOAD_CONST               0 (None)
              10 RETURN_VALUE

Thinking some more about this, this (removing the tuples) is not a 
straightforward optimisation to do.
Example 1:
     (x, y) = (y, x)
is not the same as
     x = y ; y = x
Example 2:
     L[v], y = a, f()
is not the same as
     L[v] = a ; y = f()
if v is a global changed by f().
I guess it's safe if the RHS is a tuple containing only
     constants, by which I think I mean number/string literals and 
built-in constants (None, True etc.).
     variables (NOT expressions containing variables such as "z+1") 
which do not occur on the LHS
     tuple/list/dictionary/set displays which themselves contain only 
the above, or nested displays which themselves ... etc.
It appears (even though I use Windows where timing anything is a 
nightmare) that tuple versions are slightly slower.
Rob Cliffe


More information about the Python-list mailing list