我正在学习Python OOP并尝试将Java类转换为Python类
请参阅本PDF中的第15页,了解Java代码google doc link
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
个关键字。有没有更好的方法来写这个课?
答案 0 :(得分: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
,而不是在方法内部使用任何变量。
答案 1 :(得分: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所指出,以及使用enumerate
代替range(len(self.id))
上的循环。
使用快捷方式可以更有效率(因为您保存对__getattr__
的调用),但不应该损害可读性。
答案 2 :(得分: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)
并使您的代码可重复用于其他用途。