An exercise to help build the right mental model for Python data.

The “Solution” link visualizes execution and reveals what’s actually happening using 𝗺𝗲𝗺𝗼𝗿𝘆_𝗴𝗿𝗮𝗽𝗵: https://github.com/bterwijn/memory_graph

  • m532@lemmygrad.ml
    link
    fedilink
    arrow-up
    1
    ·
    5 hours ago

    Let’s look at the suspects.

    b.append(), you add to the existing list. This mutates the current list. You can not be the culprit.

    b = b + [], you join up lists, making a new list in the process, that then gets stored in variable b, without changing the original list that’s still stored in variable a. You are not the culprit either.

    No, the culprit must be someone that ambiguously looks both like a mutation and an instantiation.

    Isn’t that right, b += []? Because the culprit… IS YOU!

    • bterwijn@programming.devOP
      link
      fedilink
      arrow-up
      3
      ·
      9 hours ago

      It’s definitely not the same. Similarly for a class you can define the __add__ dunder method for a + b and separately the __iadd__ dunder method for a += b. The first creates a new object, the latter changes/mutates the existing object a. For immutable types it is the same though.

      • JATothrim_v2@programming.dev
        link
        fedilink
        arrow-up
        4
        ·
        6 hours ago

        For immutable types it is the same though.

        The most twisted thing I learned is that all ints below a fixed limit share the same id() result, so

        >>> x = 1
        >>> id(x)
        135993914337648
        >>> y = 1
        >>> id(y)
        135993914337648
        

        But then suddenly:

        >>> x = 1000000
        >>> id(x)
        135993893250992
        >>> y = 1000000
        >>> id(y)
        135993893251056
        

        Using id() as a key in dict() may get you into trouble.

      • kibiz0r@midwest.social
        link
        fedilink
        English
        arrow-up
        2
        ·
        8 hours ago

        Oh absolutely, I understand that the language allows implementations to violate my proposed equivalence — I’m saying that’s a bad implementation (some might say a bad language, for allowing bad implementations, but I don’t necessarily agree)

  • Oka@sopuli.xyz
    link
    fedilink
    arrow-up
    2
    ·
    8 hours ago

    I expect A if “b” is a clone, or E if it’s a reference. But I also wouldnt combine array operations like this.

    The answer being C feels like a bug.

    • tomenzgg@midwest.social
      link
      fedilink
      English
      arrow-up
      2
      ·
      6 hours ago

      Eh, I get it. The equal operator creates a reference but the plus operator isn’t destructive so it creates a new list and overwrites the variable b with a new list, when assigned.

      Of course, this would all be avoided if creating copies was the norm; which is why I stick with functional languages.

      • bterwijn@programming.devOP
        link
        fedilink
        arrow-up
        1
        ·
        2 hours ago

        Copying a list with a million elements every time you make a small change is not fun. Sure, you can optimize a bit behind the scenes, but that still gives a lot of overhead.

  • aev_software@programming.dev
    link
    fedilink
    arrow-up
    3
    ·
    11 hours ago

    Tell me again how python is easy to learn for beginner programmers.

    Other languages that have similar behavior include Java and JavaScript, and yes you have to be careful with list / array operations in those languages as well, lest you operate on the wrong list inadvertently. Happened to me. It will happen to you.

    • vonbaronhans@midwest.social
      link
      fedilink
      arrow-up
      1
      ·
      9 hours ago

      You don’t have to compile. You don’t need semicolons.

      Python was my first programming language, and those two things alone honestly are really nice. Doesn’t mean there aren’t a million other issues and difficulties, though, lol.