Issue
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
Solution
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:
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.
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.
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 str_t = str
and then str_t += str
, it would just work exactly like you expected the list to work. And that's because:
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 iny
into a one as well.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.
Answered By - mtraceur
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.