0

I have a Class called Heap. In it i have declared three separate lists (min_list, max_list and xor_list). When build_heap is called, it creates a heap list over some inital input list. I then set all three lists (min,max and xor) to the heap list. So they shouldn't be linked in any way. But when I do something like

self.min_list[2] = "6"

it changes all of the three lists. My code is below:

class Heap:
def __init__(self):
    self.heap_list = [None]
    self.currentSize = 0
    self.alist = []
    self.min_list = []
    self.max_list = []
    self.xor_list = []
    self.i = 0
    self.list_start = 0
    self.SCA = 0
    self.interval_to = 0  # interval in initial list, not in heap numbering
    self.interval_from = 0

def build_heap(self, alist):
    i = 0
    self.alist = alist
    while len(alist) > (2**i):
        i += 1
    self.i = i
    self.list_start = (2**self.i)
    for j in range(len(alist)):
        self.heap_list.insert(self.list_start + j, alist[j])
    for k in range((2**self.i)-1):
        self.heap_list.insert(k, None)
    # append None to list
    # print(len(alist))
    for l in range((2**self.i)-len(alist)):
        # print("lol")
        self.heap_list.append(None)
    tup_list = self.heap_list
    self.min_list = tup_list
    self.max_list = tup_list
    self.xor_list = tup_list

def smallest_common_ancestor(self):
    bin_from = list(bin(int(self.interval_from) + int(self.list_start))[2:])
    bin_to = list(bin(int(self.interval_to) + int(self.list_start))[2:])
    smallest_common_ancestor = ""
    p = 0
    while len(bin_to) > p:
        if bin_to[p] == bin_from[p]:
            print(p)
            smallest_common_ancestor = smallest_common_ancestor + str(bin_to[p])
        p += 1

    self.SCA = int(smallest_common_ancestor, 2)

def low_id(self):
    print("Min_list before change: {}".format(self.min_list))
    int_from = int(self.interval_from) + int(self.list_start)
    int_to = int(self.interval_to) + int(self.list_start)
    m = int_to // 2

    while m + 1 != self.SCA:
        if (m * 2) == int_to:
            self.min_list[m] = self.min_list[(m * 2)]

        elif ((m*2) + 1) == int_from:
            self.min_list[m] = self.min_list[(m * 2) + 1]

        elif self.min_list[m * 2] is None:
            if self.min_list[(m * 2) + 1] is None:
                self.min_list[m] = None
            else:
                self.min_list = self.min_list[(m * 2) + 1]

        elif self.min_list[(m * 2) + 1] is None:
            self.min_list[m] = self.min_list[m * 2]

        elif int(self.min_list[m * 2]) >= int(self.min_list[(m * 2) + 1]):
            self.min_list[m] = self.min_list[(m * 2) + 1]

        else:
            self.min_list[m] = self.min_list[(m * 2)]
        m -= 1
    return self.min_list[self.SCA]

At the beginning i do something along these lines, it shouldn't be the part of the problem

heap = Heap()

heap.build_heap(input_list)

heap.interval_to, heap.interval_from = f.readline.split()

Community
  • 1
  • 1
Lipovlan
  • 23
  • 1
  • 5

1 Answers1

1
def build_heap(self, alist):
    # ...
    tup_list = self.heap_list
    self.min_list = tup_list
    self.max_list = tup_list
    self.xor_list = tup_list

This is where your class "links" the lists. Python is pass-by-reference, so min_list, max_list, xor_list, tup_list and heap_list will all point to the same object after you've called build_heap().

To create independent lists with the same values, you need to explicitly copy them:

new_list = list(old_list)
avramov
  • 2,119
  • 2
  • 18
  • 41