Есть ли в Python способ назначить переменную так, чтобы она всегда указывала на память, на которую указывает ее назначенная правая часть? - PullRequest
0 голосов
/ 13 июня 2019

Эта проблема возникла при попытке улучшить алгоритм кластеризации.Мне нужны метки для формирования цепочки и присвоения ей значения в конце цепочки.

Более простая версия проблемы описана ниже.

A = []
B = []
C = []

C = B
B = A
A.append(0)

Это дает: A = [0], B = [0], C = []

Я хочу что-то, что мгновенно обновит все элементы, когда будет достигнут конец и отредактирован.Как будто я хочу, чтобы все A, B и C были связаны вместе и обновлялись при изменении A.Ожидаемый результат: A = [0], B = [0], C = [0] ... (Эта цепочка может быть любой длины. Она может даже развивать ветви.)

Как мне добиться этого?Я назвал заголовок таким образом, потому что чувствовал, что это можно сделать, если C указывает на то, где A указывает, когда B = A выполняется.

Примечание: я не могу отслеживать заголовок всей цепочки за раз,Эта часть связывания переменных выполняется в каком-то другом порядке.

Примечание. Это соединение формируется по частям.Так что A = B = C = [0] не поможет.

Ответы [ 3 ]

1 голос
/ 13 июня 2019

Вы можете сделать это так:

>>> A = B = C = []
>>> A.append(0)
>>> A
[0]
>>> B
[0]
>>> C
[0]

В Python переменная действует как указатель на значение. Когда вы запускаете A = B = C = [], вы в основном говорите, что A, B и C указывают на один и тот же список в памяти.

В качестве альтернативы вы можете сделать следующее:

>>> A = B = []
>>> C = A
>>> C.append(0)
>>> A
[0]
>>> B
[0]
>>> C
[0]
>>> B.append(1)
>>> A
[0, 1]
>>> B
[0, 1]
>>> C
[0, 1]
0 голосов
/ 15 июня 2019

Ссылки:

Большое спасибо Безумному физику , cdrake и Рафаэлю за ваши предложения, которые направили меня в ту сторону, в которой ячтобы получить ответ, необходимо войти в систему.

Ответ:

Хитрость заключается в том, чтобы никогда не выполнять назначения, такие как C = B; B = A;, поскольку это приведет к потере информации, когда переменные начнут ссылаться на новые объекты.а старые объекты заброшены и оставлены для некоторых переменных, к которым бесполезно обращаться.

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

# Initial Declaration
A = []; B = []; C = []; D = []

# Chain Formation
C.append(B)
B.append(A)
D.append(C)

# Data Addition at Chain head
A.append("DATA")

Это дает:

>>> A
['DATA']

>>> B
[['DATA']]

>>> C
[[['DATA']]]

>>> D
[[[['DATA']]]]

Теперь у каждой из переменных есть доступ к данным, добавленным в Chain Head.Эти данные могут быть получены путем многократного ввода в индекс 0 списка, пока мы не достигнем объекта, который не имеет типа <class 'list'>.Реализация, приведенная ниже, прояснит:

def GetData(Chain):
    C = Chain.copy()
    while len(C) > 0 and type(C[0]) == type([]):
        C = C[0]
    if len(C):
        return C[0]
    else:
        return None

>>> ( GetData(A), GetData(B), GetData(C), GetData(D) )
('DATA', 'DATA', 'DATA', 'DATA')

Этот способ хранения информации с целью направления предыдущих членов к тому же источнику информации, что и глава Цепи, очень полезен, поскольку он может мгновенно передаватьизменение окончательной информации для членов на спине.Пример, основанный на предыдущем коде, показан ниже:

# Initial Declaration for New Chain
P = []; Q = []

# New Chain Formation
Q.append(P)

# Old Chain Redirection
C.remove(C[0])
C.append(Q)

# Attempted Data Recovery
>>> ( GetData(A), GetData(B), GetData(C), GetData(D), GetData(P), GetData(Q) )
('DATA', 'DATA', None, None, None, None)

# Data Addition at New Chain Head
P.append((0,0))

# Attempted Data Recovery
>>> ( GetData(A), GetData(B), GetData(C), GetData(D), GetData(P), GetData(Q) )
('DATA', 'DATA', (0, 0), (0, 0), (0, 0), (0, 0))

Это мое решение проблемы, с которой я столкнулся.Пожалуйста, не стесняйтесь предлагать изменения в случае необходимости.

Еще раз спасибо всем, кто направил меня к этому решению.

0 голосов
/ 13 июня 2019

Все в Python является объектом. Переменные - это просто имена, не имеющие отношения к местоположениям.

Имена относятся к объектам. Имена вводятся с помощью операций связывания имен.

Модель исполнения: именование и связывание - документация по Python 3.7.3

Каждый variable в Python - это просто имя, которое связано с одним объектом.

Для variable в Python ничто не является постоянным, кроме самого имени.

Однако variable в C действительно memory location.

// c
// variable a has one location
// variable b has one location, too
// they are of course different
int a, b; 

// value of location of variable a will become 4
a = 4; 

// location of variable b don't change
// what changed is 
// value of location of variable b 
// will become value of location of variable a
b = a; 
# python
# variable a(just a name) is bound to object 4
a = 4

# variable b(just a name) is bound to the object which variable a is bound
b = a

# variable b(just a name) is bound to another object 6
# nothing to with variable a(just a name)
b = 6

Итак:

Есть ли в python способ назначить переменную так, чтобы она всегда указывала на память, на которую указывает назначенная ей правая сторона?

Не в Python. Переменные в Python просто не указывают непосредственно на память. Переменные - это просто имена.

...