Reputation: 167
I fould that I can't use parameter in function without changing it.
For example:
l=[ 5, 0, 0, 0, 0, 0, 0, 0, 2 ]
def format_print(problem):
print_out = problem
for i in range(len(print_out)):
if print_out[i] == 0:
print_out[i] = "."
print(print_out)
format_print(l)
I want l to stay equal l=[ 5, 0, 0, 0, 0, 0, 0, 0, 2 ] and print_out to be [5, '.', '.', '.', '.', '.', '.', '.', 2]
Now, they are both equal [5, '.', '.', '.', '.', '.', '.', '.', 2]
Is there a way to implement it?
Thank you in advance!
Upvotes: 0
Views: 939
Reputation: 678
This is what is going on behind the scene:
[ 5, 0, 0, 0, 0, 0, 0, 0, 2 ]
and store it somewhere in memory=
, you add a label l
to that particular spot in your memoryformat_print(l)
, you pass, via the name l
the location of that particular spot in your memoryproblem
, then a third label print_out
to that exact same object you first createdDuring all this process, there is only one list that exists (even though it now responds to 3 different names). So as you modify l
, print_out
, or problem
, you're modifying that one version of your object.
One solution, would be to explicitly create copies of your object. However, I think that can get quickly confusing. What if you start having nested lists? You now need to worry about copying those too.
While it may not be the most efficient, in general, the safest way, to write your functions is to create a brand new list which you will populate as you traverse your original list:
l = [ 5, 0, 0, 0, 0, 0, 0, 0, 2 ]
def format_print(problem):
solution = [None] * len(problem)
for i, v in enumerate(problem):
solution[i] = v if v != 0 else '.'
print(solution)
In your particular case, you can be quite concise:
solution = [v if v != 0 else '.' for v in l]
Upvotes: 0
Reputation: 85615
Don't made printout equal to l (because what you get is not a new object but a reference to the same object), use another list
l = [ 5, 0, 0, 0, 0, 0, 0, 0, 2 ]
def format_print(problem):
print_out = []
for item in problem:
if item == 0:
print_out.append(".")
else:
print_out.append(item)
print(print_out)
In any case, you do not need any function because you can resolve the problem with a list comprehension:
problem = [ 5, 0, 0, 0, 0, 0, 0, 0, 2 ]
print_out = [item if item !=0 else '.' for item in problem]
As said in another post map
is also a good and more general option
Upvotes: 0
Reputation: 5395
Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.
You can use copy()
function with will copy list, not point it to new var.
import copy
list1 = [1,2,3,4]
# First List
print(id(list1), " is ", list1 )
list2 = list1
# First List
print(id(list2), " is ", list2 )
list3 = copy.copy(list2)
# First List
print(id(list3), " is ", list3 )
But, its better to use map()
, in your example function to filter/map values in your list.
list1 = [0, 1,2,3,4]
# First List
print(id(list1), " is ", list1 )
def dot(x):
return "." if x == 0 else x;
list2 = map(dot, list1);
print(id(list2), " is ", list2 )
print(id(list1), " is ", list1 )
Upvotes: 1