Recursive function call not adding values to list

Viewed 70

I am creating a Tensor by using lists and without the aid of libraries. The class Tensor has a method called, shape_data, which creates the Tensor by taking in the dimension and sublist.

  def shape_data(self, dim, sub):
    if dim >= len(self.shape):
      return
    elif (len(sub) == 0) & (dim < (len(self.shape) - 1)):
      for i in range(self.shape[dim]):
        sub.append([])
        self.shape_data(dim + 1, sub[i])
    elif len(sub) == 0:
      if len(self.data) > self.shape[dim]:
        sub = self.data[0:self.shape[dim]]
        self.data = self.data[self.shape[dim]:]
      elif len(self.data) <= self.shape[dim]:
        sub = self.data[0:]
        self.data = []
        while len(sub) != self.shape[dim]:
          sub.append(0)

data0 = [0, 1, 2, 3, 4, 5, 0.1, 0.2, -3, -2, -1, 3, 2, 1]
shape0 = [5, 2]
tensor0 = Tensor(data0, shape0)

This is the output that I get [[], [], [], [], []] vs. what I want [[0, 1], [2, 3], [4, 5], [0.1, 0.2], [-3, -2]]

My question is, what am I missing here that the numbers are not being copied over successfully?

1 Answers

I suspect, that the problem is in following line:

sub = self.data[0:self.shape[dim]]

If you assign something to the variable sub , it will from then on point to the new value. The value it pointed to before that assignment (your original list) will stay unchanged.

If you, instead, assign something to elements of that list, this will change the original list:

sub[:] = self.data[0:self.shape[dim]]

Same affects this line as well:

sub = self.data[0:]

Here is corrected code:

class Tensor():
    
  def __init__(self, data, shape):
    self.data = data
    self.shape = shape
    self.tensor = []
    self.shape_data(0, self.tensor, 0)
    print(self.tensor)

  def shape_data(self, dim, sub, pos):
    if dim >= len(self.shape):
      return
    elif (len(sub) == 0) & (dim < (len(self.shape) - 1)):
      for i in range(self.shape[dim]):
        sub.append([])
        self.shape_data(dim + 1, sub[i], i)
    elif len(sub) == 0:
      if len(self.data) > self.shape[dim]:
        sub[:] = self.data[0:self.shape[dim]]
        self.data = self.data[self.shape[dim]:]
      elif len(self.data) <= self.shape[dim]:
        sub[:] = self.data[0:]
        self.data = []
        while len(sub) != self.shape[dim]:
          sub.append(0)
Related