копировать переменную по значению, а не по ссылке - PullRequest
0 голосов
/ 08 ноября 2018

совершенно новый для python и пытается получить копию значения переменной. У меня есть алгоритм, который вызывает рекурсивно другой, но не получает желаемых значений, так как я думаю, что вместо использования ссылки я присваиваю одну переменную другой в следующем коде:

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

я хочу иметь в depthact то же значение, что и deepi , но вместо этого я думаю, что я указываю на ту же область памяти и, следовательно, при вызове limSearch я делаю оно с любым значением, переданным методу в deepi , вместо другого, которое я хочу использовать, так как затем увеличиваю его.

я прав? любая помощь будет высоко ценится.

edit: Я знаю, что решение алгоритма limSearch находится в глубине = 35, но я хочу, чтобы этот другой алгоритм проверял, существует ли решение для данного приращения глубины, поэтому, если я вызываю поиск с глубиной = 40 и глубиной 2, он должен запустить limSearch, передавая вначале depthact значение 2, затем 4, 6, 8, 10 .. до тех пор, пока не достигнет 36, тогда он должен найти причину, по которой он находится в 35, но он делает не работает, вместо этого я получаю sol = None во всех случаях, как если бы я вызывал limSearch с другими значениями.

def search (задача, стратегия, 40, 2, обрезка):

Я хочу, чтобы такой вызов был в цикле вызова limSearch, пока он не достигнет решения в этом алгоритме, который в данном случае имеет глубину = 35. поэтому мой ожидаемый результат:

sol = limSearch (задача, стратегия, 2, обрезка)

sol = limSearch (задача, стратегия, 4, обрезка)

sol = limSearch (проблема, стратегия, 6, обрезка)

...

sol = limSearch (проблема, стратегия, 36, обрезка)

в этой последней итерации sol не будет равен none, и тогда цикл while больше не будет выполняться, возвращая мне желаемое решение.

контекст, в котором я вызываю эту функцию, следующий:

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

после считывания всех значений значений пользовательским вводом.

depthl = int(input('depth: '))-1
if(strategy == 3): depthi = int(input('depth increment: '))

1 Ответ

0 голосов
/ 08 ноября 2018

Как правило, если у вас есть проблемы со ссылками и копированием данных, модуль копирования предоставит вам точный контроль копирования, который вы ищете.

copy.copy гарантированно делает «мелкую копию», где список будет содержать ссылки на старые данные, но будет новым списком (или другим контейнером).

copy.deepcopy даст вам "глубокую копию", куда будут скопированы сами элементы.

В этом случае, однако, у вас есть простой тип int и он неизменный, поэтому каждый раз при изменении значения создается новый экземпляр. (Это немного сложнее, чем с неизменяемыми объектами, но дело в том, что если вы используете простые типы, то оператор присваивания = не будет модифицировать другие экземпляры тех назначенных вами симплектных типов.)

т

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

Это печатает "42" и "43", показывая, что изменение b не изменит a.

Если вы не копируете универсальный тип, вам следует скопировать модуль. Произвольные классы могут реализовывать методы __copy__ и __deepcopy__ ( больше информации ) для создания копий объекта и являются наиболее питоническим способом гарантировать, что копии создаются так, как ожидают пользователи.

Edit: Для тех, кто будет редактировать посты, чтобы убрать от первого лица голос моего ответа; не делай этого. Я отвечаю на ФП, а не пишу технический журнал, и считываемость . Я принимаю, что мой ответ был неверным, но только потому, что я предложил использовать конструктор типа int, когда в этом не было необходимости (хотя результат был бы таким же, это был не pythonic ). И я включил немного об неизменяемых типах данных здесь, но я не чувствую, что сказать, что «int является неизменяемым», является достаточным ответом, потому что явное лучше, чем неявное . Сказав это, знание неизменяемых типов и модуля стандартной библиотеки copy, вероятно, является наиболее полным ответом.

...