The first thing to understand is why that setEqual
method can't work: you need to know how identifiers work. (Reading that link should be very helpful.) For a quick rundown with probably too much terminology: in your function, the parameter restore
is bound to an object, and you are merely re-binding that identifier with the =
operator. Here are some examples of binding the identifier restore
to things.
# Bind the identifier `restore` to the number object 1.
restore = 1
# Bind the identifier `restore` to the string object 'Some string.'
# The original object that `restore` was bound to is unaffected.
restore = 'Some string.'
So, in your function, when you say:
restore = []
You are actually binding restore to a new list object you're creating. Because Python has function-local scoping, restore
in your example is binding the function-local identifier restore
to the new list. This will not change anything you're passing in to setEqual
as restore. For example,
test_variable = 1
setEqual(test_variable, [1, 2, 3, 4])
# Passes, because the identifier test_variable
# CAN'T be rebound within this scope from setEqual.
assert test_variable == 1
Simplifying a bit, you can only bind identifiers in the currently executing scope -- you can never write a function like def set_foo_to_bar(foo, bar)
that affects the scope outside of that function. As @Ignacio says, you can use something like a copy function to rebind the identifier in the current scope:
original = [1, 2, 3, 4]
backup = list(original) # Make a shallow copy of the original.
backup.remove(3)
assert original == [1, 2, 3, 4] # It's okay!