3

我正在学习 Python OOP 并尝试将 Java 类转换为 Python 类

有关 Java 代码 google doc链接,请参阅此 PDF 中的第 15 页

class QuickFindUF:
        """docstring for QuickFindUF"""


    def __init__(self, n):
            self.id = []
            for e in range(n):
                    self.id.append(e)


    def connected(self,p,q):
            return self.id[p]==self.id[q]

    def union(self,p,q):
            self.pid = self.id[p]
            self.qid = self.id[q]
            for i in range(len(self.id)):
                    if(self.id[i]==self.pid):
                            self.id[i]=self.qid


quf = QuickFindUF(9)
quf.union(3,4)
print quf.connected(3,4)

这个类有16个self关键字。有没有更好的方法来编写这个类?

4

3 回答 3

7

是的,您不想将这些变量分配给self,这些是局部变量:

def union(self,p,q):
        self.pid = self.id[p]
        self.qid = self.id[q]
        for i in range(len(self.id)):
                if(self.id[i]==self.pid):
                        self.id[i]=self.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:
            self.id[i] = qid

您仅self在引用实例变量时使用,而不是方法内的任何变量。

于 2012-08-13T23:26:12.470 回答
1

您可以使用一些快捷方式:

class QuickFindUF:
    """docstring for QuickFindUF"""

    def __init__(self, n):
        self.id = range(n)

    def connected(self,p,q):
        _id = self.id
        return _id[p]==_id[q]

    def union(self,p,q):
        _id = self.id
        pid = _id[p]
        qid = _id[q]
        for (k, _i) in enumerate(_id):
           if (_i == pid):
               _id[k]=qid

请注意__init__@katrielalex 所指出的 中的简化,以及使用 ofenumerate而不是循环 on range(len(self.id))

使用快捷方式可能更有效(当您保存对 的调用时__getattr__),但不应损害可读性。

于 2012-08-13T23:52:48.517 回答
0

像这样使用list(range())和:enumerate

class QuickFindUF:
    
    def __init__(self, n):
        self.id = list(range(n))

    def connected(self, i, j):
        return self.id[i] == self.id[j]

    def union(self, i, j):
        x = self.id[i]
        y = self.id[j]
        for index, elem in enumerate(self.id):
            if elem == x:
                self.id[index] = y

但更好的是:不要忘记 Python 是多范式的。如果方法具有通用方面,则将这些方面外包给纯函数:

def map_each_x_to_y(array, x, y):
    for i, elem in enumerate(array):
        if elem == x:
            array[i] = y
    return array

def map_ith_values_to_jth(array, i, j):
    x = array[i]
    y = array[j]
    return map_each_x_to_y(array, x, y)

这种更具声明性的风格可能看起来很冗长,但它使union方法意图的期望行为更容易理解:

    def union(self, i, j):
        self.id = map_ith_values_to_jth(self.id, i, j)

并使您的代码更可重用于其他事情。

于 2020-08-18T09:25:07.910 回答