-1
def append_arr(arr):
  t_arr = arr
  print('arr before',arr)
  t_arr.extend(arr)
  print('arr affter',arr)
arr = ['a','b','c']
append_arr(arr)

I had list a, assign b=a, and change list b by functions (append, insert, extend) I didn't touch list a any more, but when b change, a is also change follow b.

How to change b by (append, insert, extend) and a not change

def test():
  arr_m = ['a','b','c']
  print('arr_m before', arr_m)
  append_arr(arr_m)
  print('arr_m affter', arr_m)
test()
arr_m before ['a', 'b', 'c']
arr before ['a', 'b', 'c']
arr affter ['a', 'b', 'c', 'a', 'b', 'c']
arr_m affter ['a', 'b', 'c', 'a', 'b', 'c']

I don't know why arr_m change too

  • 3
    Welcome to SO. Please see the help on how to ask a question. If you want people to help, you'll need to provide a minimal example of what you've tried that runs and shows a wrong result. Another hint is that using "stupid" in the question title to describe a pretty good language is not likely to inspire folks to help. – Gene Nov 03 '22 at 02:56
  • Please don't post code as an image, post it as text. – Dijkgraaf Nov 03 '22 at 02:58
  • You're not going to get much positive attention on your question if you frame it in a ranty, hostile way. Nobody wants to deal with that. You don't understand that assignment of an object copies a reference to the same object (it _doesn't_ copy the object itself). Before you criticize anything as stupid, at least understand it first. – Alexander Nov 03 '22 at 02:58
  • Anyway, you are passing around only 1 mutable object by reference, which you are then adding to itself. If you were to print the `id(arr_m)` , t_arr or whatever, you'd find this is the same object *everywhere*. https://docs.python.org/3/library/functions.html#id – JL Peyret Nov 03 '22 at 03:02
  • This question is an extremely good example of how and why mutable state (especially when there are multiple shared references to mutable state) is unintuitive and terrible UX/DX. Normal humans who aren't mind-bent like we are don't find it sensible or expected - recognize that Asker is expressing a normal and common human reaction to the way our languages work. – mtraceur Nov 03 '22 at 03:08

1 Answers1

-1

You are expecting t_arr = arr to make a new list which has the same contents, but all it does is make a second name which refers to the same list.

It works like this because:

  1. A lot of programming languages were designed based on how computers work. It is normal to think of lists as things, but at the low level in a computer a list is more like a place - the spot in memory where all of the list's contents are stored. To this day many programmers are used to "place-oriented programming" (though almost nobody calls it that), and Python was written way back in 1991 or so.

  2. Until recently, languages where everything was immutable, or where assignment did a copy by default, were often far less efficient - it takes some tricky optimizations to turn code that semantically always makes a copy into machine operations that only copy the minimum of data only when they need to. So back when Python was new, it would've been a lot slower and would've used a lot more memory if it had been designed to make copies all the time.

  3. Programmer culture has not yet finished understanding "the value of values" (a great video by Rich Hickey, the creator of the language Clojure which unlike Python doesn't behave this way) - so we've still got a lot of place-oriented shared-mutable-state-by-default languages in widespread use and most people don't see it as a big deal or major problem.

But now you might be thinking "but why doesn't that happen with integers and strings!?" And you'd be right, if you did t_string = string and then t_string += string, it would just work exactly like you expected the list to work. And that's because:

  1. Integers were historically a special case because they're so small in a computer, and so fundamental to computer operations, that it was often more efficient, or in any case efficient enough, to implement them as immutable values. But perhaps also people had an easier time understanding intuitively that it would be insane if x = 0; y = x; x += 1 turned the zero in y into a one as well.

  2. Strings were deliberately made immutable, even though they're basically lists, because by the time Python was being made, the world of programming had seen so many pitfalls (and reactions like yours from new programmers) to strings being mutable that "strings should be immutable" managed to overcome the tradition of mutable state enough, especially for languages that were aiming to be more human-friendly like Python, despite the memory and speed costs.

The linked duplicate question will show you how to make it instead do what you want, and has some other decent elaborations on why it works this way.

mtraceur
  • 3,254
  • 24
  • 33