copy variable by value not reference
Asked Answered
B

2

7

quite new to python and struggling to achieve a value copy of a variable. have an algorithm that calls recursively another one but not getting the desired values since i think im instead using reference when assigning one variable to another in the following code:

def search(problem, strategy, depthl, depthi, pruning):
    depthact = depthi
    sol = None
    while(not sol and depthact <= depthl):
        sol = limSearch(problem, strategy, depthact, pruning)
        depthact += depthi
    return sol

i want to have in depthact the same value as depthi but instead i think im pointing to the same memory location and therefore when calling limSearch im doing it with whatever value is passed to the method in depthi instead of the other one that is the one i wanna use since i then increment it.

am i right? any help will be much appreciated.

edit: i know the solution to the limSearch algoritm is in a depth=35 but want this other algorithm to check if a solution exits for a given depth increment so, if i call search with depthl=40 and a depthi of 2, it should run limSearch passing in depthact the value 2 at first, then 4, 6, 8, 10.. until it reaches 36 that then it should find the solution cause of it being in 35 but it does not work, instead im getting a sol=None in all cases as if i was calling limSearch with other values.

def search(problem, strategy, 40, 2, pruning):

i want a call like this one to be in the loop calling limSearch until it reaches a solution in that algorithm that in this case is in depth=35. so my expected result is:

sol = limSearch(problem, strategy, 2, pruning)

sol = limSearch(problem, strategy, 4, pruning)

sol = limSearch(problem, strategy, 6, pruning)

...

sol = limSearch(problem, strategy, 36, pruning)

in this last iteration sol will not be none and then the while loop will no longer be executed returning me the desired solution.

the context where i call this function is the following:

if(strategy == 3): sol = search(p, strategy, depthl, depthi, pruning)
else: sol = limSearch(p, strategy, depthl, pruning)

after reading all the values values by user inputs.

depthl = int(input('depth: '))-1
if(strategy == 3): depthi = int(input('depth increment: '))
Biodegradable answered 8/11, 2018 at 18:54 Comment(0)
A
6

Generally, if you have concerns with references and copying data, the copy module is going to give you the fine-grained copy control you're looking for.

copy.copy is guaranteed to do a "shallow copy", where a list will contain references to the old data, but will be a new list (or other container).

copy.deepcopy will give you a "deep copy" where the elements themselves will be copied.

In this case though, you have a simple type int and is immutable, therefore a new instance is created whenever the value is changed. (It's a bit more complicated than that with immutable objects, but the point is that if you're using simple types than the assignment operator = will not modify other instances of those symple types that you've assigned.)

ie:

a = 42
b = a
b +=1
print(a)
print(b)

This prints "42" and "43" showing that modifying b will not modify a.

If you're not copying a generic type than you should copy module. Arbitrary classes can implement methods __copy__ and __deepcopy__ (more info) to make copies of object and is the most pythonic way to ensure that copies are made the way that users expect.

Edit: To those that would edit posts to remove the first person voice of my response; do not do that. I an answering the OP and not writing a technical journal, and readability counts. I accept that my answer was incorrect, but only in that I suggested the use of the int type constructor when it was not necessary (although the result would have been the same, it was not pythonic). And I've included the bit about immutable data types here, but I do not feel that saying that "int is immutable" is a sufficient answer because being explicit is better than implicit. Having said that, knowledge of immutable types and the standard library copy module is probably the most complete response.

Assamese answered 8/11, 2018 at 19:2 Comment(2)
In what circumstance would making a copy of an integer ever make a difference except when doing identity checks with is, which isn't being used here?Siesta
And even then, is is fallible due to cached integers in some cases.Selenodont
D
0

If you want to copy an int or a float or something like that, you can always try casting the value to a string and then back to the original type:

a = 20
b = int(f"{a}")

print(a, b)
a = 8181
print(a, b)
a = 1111
b = 123
print(a, b)

Output:

20   20
8181 20
1111 123

Another method to support additional values, and arguably the simplest, is to write a function that just returns the value:

def copy_value(value_to_copy):
    return value_to_copy
Danford answered 12/11, 2022 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.