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