git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

a,b = 2,3 and [a,b] = [2,3]


On Mon, Sep 2, 2019 at 12:36 PM Alan Bawden <alan at csail.mit.edu> wrote:
>
> Eko palypse <ekopalypse at gmail.com> writes:
>
> > Am Montag, 2. September 2019 00:49:05 UTC+2 schrieb Hongyi Zhao:
> > > Hi,
> > >
> > > What's differences:
> > >
> > > a,b = 2,3 and [a,b] = [2,3]
> > >
> > > Regards
> >
> > In this example the result is the same but the second one
> > builds, internally, an additional list, therefore isn't as sufficient
> > as the first one.
>
> It looks to me like they generate identical code.  The first one calls the
> construction of a tuple, where the second one calls for the construction of
> a list.  It would be surprising if the compiler optimized the tuple
> away, but failed to optimize the list away!
>

Well, you can find out with the 'dis' module.

>>> def f():
...     a, b = 2, 3
...     a, b = [2, 3]
...
>>> dis.dis(f)
  2           0 LOAD_CONST               1 ((2, 3))
              2 UNPACK_SEQUENCE          2
              4 STORE_FAST               0 (a)
              6 STORE_FAST               1 (b)

  3           8 LOAD_CONST               2 (2)
             10 LOAD_CONST               3 (3)
             12 BUILD_LIST               2
             14 UNPACK_SEQUENCE          2
             16 STORE_FAST               0 (a)
             18 STORE_FAST               1 (b)
             20 LOAD_CONST               0 (None)
             22 RETURN_VALUE

This is with CPython 3.9. It's entirely possible that other Pythons
and/or other versions of CPython may give different results, but with
this particular interpreter, the list is not optimized away.

Tuples get optimized away in quite a number of situations. Exchanging
is done on the stack:

>>> def f():
...     x, y = y, x
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (y)
              2 LOAD_FAST                1 (x)
              4 ROT_TWO
              6 STORE_FAST               1 (x)
              8 STORE_FAST               0 (y)
             10 LOAD_CONST               0 (None)
             12 RETURN_VALUE

There are a lot of assumptions the interpreter can make about them,
including that they cannot nest recursively [1], and that, when
constructed from constants, they are themselves constant. Any time you
think it'll make no difference, go with a tuple.

ChrisA

[1] Technically they can, but you have to use the CPython API or
equivalent - vanilla Python code can't do it.