简体   繁体   中英

Why can't I change the values of a list in the class using a method?

I'm trying to implement simple Quick Find algorithm using python. This is the first time I am using OOP in Python. Following are the steps I took:

  1. Create the class with init method so that it accepts N no. of elements for the list - "id", and I append the 0 - N-1 elements to the list.

     class QuickFindUF: def __init__(self, N): self.id = [] for i in range(N): self.id.append(i)
  2. I create a union method which accepts the arguments: p & q(these are the values that I want to connect) and then change the list values so that the list items which have pid are changed to qid.

     def union(self,p, q): pid = self.id[p] qid = self.id[q] for i in range(len(self.id)): if self.id[i] == pid: # This part is getting ignored, I think. self.id[i] == qid
  3. I create get_id method to see the changes in the id.

     def get_id(self): return self.id
  4. Now in the main part I do this to see the results:

    if __name__ == "__main__":

     qf = QuickFindUF(5) print(qf.get_id()) qf.union(0, 3) print(qf.get_id())

I should see the updated id[] after I call the union method but id doesn't change.
Expected output: [0, 1, 2, 3, 4] [3, 1, 2, 3, 4]
Actual output: [0, 1, 2, 3, 4] [0, 1, 2, 3, 4]

I tried to change some values of id manually without using the "if" statement in union method and that worked out fine, like: id[0] = 'a' and that worked out fine: the output was: [0, 1, 2, 3, 4] ['a', 1, 2, 3, 4]

So why is the union method not working if I use a for loop with if statements to change the values of the list?

I also tried returning the id[] in the union() like this:
def union(self,p, q):

```pid = self.id[p]
    qid = self.id[q]
    for i in range(len(self.id)):
    if self.id[i] == pid:  # This part is getting ignored, I think.
        self.id[i] == qid```

But I get the same output when I print(qf.union())

Try this

def union(self,p, q):
    pid = self.id[p]
    qid = self.id[q]
    for i in range(len(self.id)):
        if self.id[i] == pid:  # This part is getting ignored, I think.
            self.id[i] = qid

I would suggest to use numpy:

import numpy as np

class QuickFindUF:

   def __init__(self, N):
       self.id = np.arange(N)  # Quicker with numpy

   def union(self, p, q):
       pid = self.id[p]
       qid = self.id[q]
       
       # Use powerful np.where
       self.id = np.where(self.id == pid, # Where self.id = pid,
                          qid, # changes it to qid,
                          self.id)  # the rest of the array remains unchanged

   def get_id(self):
       return self.id


if __name__ == "__main__":
    qf = QuickFindUF(5)
    print(qf.get_id())
    qf.union(0, 3)
    print(qf.get_id())

If I understood your problem correctly, it should work fine. Otherwise adapt the parameters of np.where().

Good luck !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM