List of Lists: Changing All Links with a Single Assignment?

Rationale: I run a script with a list that contains several heaps. At every step, I want to “attach” the heaps, but keep both the combined indexes pointing to the same element.

In short, given the list of variable elements, such as list[a] is list[b]returns True, how do I assign ( list[a] = [new]), maintaining links list[a]and list[b]at the same variable container?

So, for example, if each heap was represented by a letter, we would have

t is ['a', 'b', 'c', 'd']
t is ['ac', 'b', 'ac', 'd'] (0 and 2 merge)
t is ['abc', 'abc', 'abc', 'd'] (0 and 1 merge, but since 0 also refers to 2, it is as if 0/2 and 1 merged... into 0/1/2)

at this stage, if I did set(map(id, t)), I would expect it to have only two elements.

my problem is that I cannot affect the object that is directly pointed to, so I have to iterate over the entire list, choosing any identifiers that match the merge index, and assign directly.

Is there a way to change the underlying object, and not all pointers to it?

Full example of desired behavior:

>>> my_list = [['a'], ['b'], ['c']]
>>> merge(my_list, 0, 2) # mutates, returns None
>>> my_list
[['a', 'c'], ['b'], ['a', 'c']]
>>> my_list[0] is my_list[2]
True
>>> merge(my_list, 0, 1)
>>> my_list
[['a', 'c', 'b'], ['a', 'c', 'b'], ['a', 'c', 'b']]
>>> my_list[0] is my_list[1]
True
>>> my_list[1] is my_list[2]
True

The problem is that if inside mergeI just call

my_list[arg1] = my_list[arg2] = my_list[arg1]+my_list[arg2]

it ONLY affects records in arg1and arg2. I want this to affect any other entries that may point to elements in my_list[arg1]or my_list[arg2], so that ultimately my_listis just a collection of pointers to the same big heap that has absorbed all the little ones.

+4
source share
3 answers

It will be as close as possible:

def merge(primary, first, second):
    primary[first] += primary[second]
    primary[second] = primary[first]

first = ['a']
second = ['b']
third = ['c']

main = [first, second, third]
print(main)
merge(main, 0, 2)
print(main)
assert main[0] is main[2]
merge(main, 0, 1)
print(main)
assert main[1] is main[2]
print(first, second, third)

and printout:

[['a'], ['b'], ['c']]
[['a', 'c'], ['b'], ['a', 'c']]
[['a', 'c', 'b'], ['a', 'c', 'b'], ['a', 'c', 'b']]
(['a', 'c', 'b'], ['b'], ['c'])

, , , , .

, , .

, . , , , , :

def merge(primary, first, second):
    targets = primary[first], primary[second]
    result = primary[first] + primary[second]
    for index, item in enumerate(primary):
        if item in targets:
            primary[index] = result
+1

:

>>> my_list = [['a'], ['b'], ['c']]

>>> my_list[0] = my_list[2] = my_list[0]+my_list[2]

>>> my_list
[['a', 'c'], ['b'], ['a', 'c']]

>>> my_list[0] += [1,2,3]

>>> my_list
[['a', 'c', 1, 2, 3], ['b'], ['a', 'c', 1, 2, 3]]

>>>

a=c=a+c, a==c==_list_object_001; a=b=a+b 2nd, a==b==_list_object_002, .
pointer, . , , .

+1

, , , python. X Y, , , . X, Y , , X, X, Y , , Y, .

, , .

class Nodes(object):
    def __init__(self, input1):
        self.parent = None
        self.val = [input1]

    def ultimate_parent(self):
        if self.parent:
            return self.parent.ultimate_parent()
        else:
            return self

    def merge(self, child):
        self.ultimate_parent().val += child.ultimate_parent().val
        child.ultimate_parent().parent = self.ultimate_parent()

    def __repr__(self):
        return str(self.ultimate_parent().val)

def merge(node_list, i, j):
    node_list[i].merge(node_list[j])


list1 = [Nodes(x) for x in 'abcd']
print list1

merge(list1, 0, 2)
print list1
merge(list1, 1, 3)
print list1
merge(list1, 0, 1)
print list1

:

[['a', 'c'],['b'],['a', 'c'],['d']]
[['a', 'c'],['b', 'd'],['a', 'c'],['b', 'd']]
[['a', 'c', 'b', 'd'],['a', 'c', 'b', 'd'],['a', 'c', 'b', 'd'],['a', 'c', 'b', 'd']]
+1

All Articles