if var1 equals 1, and you run var2 = var1, that sets var2 to 1.

if list1 equals [1, 2, 3], and you run list2 = list1, that sets list2 to list1

so if you then run var1 = 2, var2 will still be 1

but if you run list1 = [3, 2, 1], list2 will give [3, 2, 1]

  • logging_strict@programming.dev
    link
    fedilink
    arrow-up
    1
    ·
    18 hours ago

    Eww eww eww, I have a good one!

    function argument: params vs **params

    Assume both are the same Mapping.

    The former can update in-place. The later, nope.

    If the function is a generic function or one of the overloads. Wait what’s that? It’s the term used by functools.singledispatch to describe the fallback function when no overload function handles the case.

    Anyway

    Any param to either singledispatch generic or an overload, Whatever you throw at it, won’t be in-place updatable.

  • gedhrel@lemmy.world
    link
    fedilink
    arrow-up
    20
    ·
    4 days ago

    It won’t (using your example explicitly) but in general what you’ve discovered is that:

    1. Variables hold values
    2. Some of those values are references to shared mutable objects.

    Lists fall into the second category. There are ways to copy lists if you want distinct behaviour.

    list2 = list1[:]
    

    will perform a “shallow copy”. If you have a list of lists, however, the nested lists are still shared references. There is copy.deepcopy available to make a complete clone of something (including all its nested members).

      • marcos@lemmy.world
        link
        fedilink
        arrow-up
        3
        ·
        4 days ago

        Every variable in Python is actually a reference (maybe optimized out, but still logically a reference). There’s no difference.

        Numbers, booleans, and None won’t give you that kind of problem only because you can’t change them.

        • nickwitha_k (he/him)@lemmy.sdf.org
          link
          fedilink
          arrow-up
          1
          ·
          4 days ago

          True. Since it’s all interpreted, it doesn’t act like primitives in things like C and everything is an object, that is a ref of some sort. However, there is a difference between how Python “primitives” and Python collections work within the language syntax.

          • marcos@lemmy.world
            link
            fedilink
            arrow-up
            1
            ·
            4 days ago

            Now I’m curious what differences you are talking about, because I’m no Python expert, but I can’t think of any. If you mean identity representation, no, it’s not different:

            >>> a = 65535
            >>> b = 65535
            >>> a is b
            False
            
            • nickwitha_k (he/him)@lemmy.sdf.org
              link
              fedilink
              arrow-up
              0
              ·
              edit-2
              3 days ago

              I was meaning how they behave in when copying and similar behavior. One basically just needs to remember that assignment of a Python primitives var to another will copy the value, whereas doing the same thing with a collection will generally make a reference instead.

              As for this:

              >>> b = 65535
              >>> a is b
              False
              

              I’d expect that behavior in must programming languages. It effectively translates to:

              Allocate a variable "a" and assign it the value 65535
              
              Allocate a variable "b" and assign it the value 65536
              
              Is variable "a" literally the variable "b"? No
              

              One could test with == to see if the values are equivalent but, unless “b” is assigned as “a”, a is b should evaluate as false because they are two different variables.

              • logging_strict@programming.dev
                link
                fedilink
                arrow-up
                1
                ·
                17 hours ago

                Other, maybe clearer, way to inspect references

                id(a) == id(b)

                Then reserve the use of is for bool or None.

                Python has a concept of, Just don't do that. Which would be a great title for this topic thread.

              • marcos@lemmy.world
                link
                fedilink
                arrow-up
                1
                ·
                3 days ago

                It doesn’t seem to copy the value, just make another reference:

                >>> a = 65535
                >>> b = a
                >>> b is a
                True
                

                One thing I know that Python does is optimize the value away for the few smallest values of the primitives. But that’s on optimizations.

                • nickwitha_k (he/him)@lemmy.sdf.org
                  link
                  fedilink
                  arrow-up
                  2
                  ·
                  2 days ago

                  Oh right! You are indeed correct. It is effectively just seeing a pointer there. What Python considers that to be is a shallow copy. But this only applies to “primitive” types. If you change the value of either, it will cease to act as a pointer to the same object but instead allocate a new one. It’s a bit weird if one isn’t used to all of that abstraction between oneself and the memory.

  • marcos@lemmy.world
    link
    fedilink
    arrow-up
    10
    ·
    edit-2
    4 days ago

    Hum… No it won’t.

    It’s something you only really learn from C or Rust, but your operations will set both to the same list. If you go and change the list, you will change both, but if you set one to a different list, you won’t change the other list.

    In other words, if you do list1.push(4), you will change list2. But list1 = [3, 2, 1] won’t.

  • Diplomjodler@lemmy.world
    link
    fedilink
    arrow-up
    2
    ·
    edit-2
    4 days ago

    Everything’s an object. A variable is a pointer to an object. var1 is a pointer to the object 1 (which is an integer). var2 is also a pointer to the same object. If you point var1 to a different object (the integer 2), that doesn’t change var2. list1 is a pointer to the list object you defined. list2 is a pointer to the same object. If you change the object, both pointers still point to it.

    At least that’s my understanding of the whole business. If I got anything wrong, in sure somebody will point it out.