Home > front end >  Does an assignment of a variable to its own value result in an actual assignment in memory in Python
Does an assignment of a variable to its own value result in an actual assignment in memory in Python

Time:12-03

If I assign a variable to its own value like this (line 2) (after previously assigning a value):

a_list = ['a', 'list']
a_list = a_list

Does this compile down to an actual assignment or is it just skipped?

I'm asking because I want to know whether the latter of the two following code snippets suffers from a performance penalty.

def foo(a_list: list = None):
    if a_list is None:
        a_list = ['default', 'list', 'values']
def foo(a_list: list = None):
        a_list = ['default', 'list', 'values'] if a_list is None else a_list

CodePudding user response:

It is possible to verify the generated bytecode for both methods by yourself with the dis.dis call. (check @petrch `s answer)

However, the "cost" of the identity assignment will be negligible, compared to other resources your full code will be using, whatever they are: this sort of micro-optimization is not meant to be done in Python code: if CPU cycles count to this level, you should be using a language that maps directly to CPU ops, like C, GO or Rust.

That said, the first form, even taking one extra line and indentation level, is "easier to read". I'd go with the first form. Just the fact that the one-liner may divert the though train in a "maybe this is less performant" thread is not worth it (as is demonstrated by you getting to the point of asking this question)

CodePudding user response:

You can easily check it for yourself with the help of the dis module. The result may (and will probably) change across python versions: https://docs.python.org/3/library/dis.html

import dis

>>> def foo(a_list: list = None):
...         a_list = ['default', 'list', 'values'] if a_list is None else a_list
...
>>> dis.dis(foo)
  2           0 LOAD_FAST                0 (a_list)
              2 LOAD_CONST               0 (None)
              4 COMPARE_OP               8 (is)
              6 POP_JUMP_IF_FALSE       18
              8 LOAD_CONST               1 ('default')
             10 LOAD_CONST               2 ('list')
             12 LOAD_CONST               3 ('values')
             14 BUILD_LIST               3
             16 JUMP_FORWARD             2 (to 20)
        >>   18 LOAD_FAST                0 (a_list)
        >>   20 STORE_FAST               0 (a_list)
             22 LOAD_CONST               0 (None)
             24 RETURN_VALUE
>>> def foo(a_list: list = None):
...     if a_list is None:
...         a_list = ['default', 'list', 'values']
...
>>> dis.dis(foo)
  2           0 LOAD_FAST                0 (a_list)
              2 LOAD_CONST               0 (None)
              4 COMPARE_OP               8 (is)
              6 POP_JUMP_IF_FALSE       18

  3           8 LOAD_CONST               1 ('default')
             10 LOAD_CONST               2 ('list')
             12 LOAD_CONST               3 ('values')
             14 BUILD_LIST               3
             16 STORE_FAST               0 (a_list)
        >>   18 LOAD_CONST               0 (None)
             20 RETURN_VALUE
  • Related