在SparseVec(length)类中,我被赋予了使用特殊方法添加两个稀疏向量的任务。我对特殊方法和方法重载的了解有限,请您描述一下我在以下代码中缺少的内容以及确切的含义是什么方法重载? 我有两种选择:使用独立函数和类方法(OOP)。我想知道后者(OOP)的优势。
独立功能(正常工作)
def SparseVec(numbers):
dic={}
for key,val in enumerate(numbers):
if val:
dic[key]=val
return dic
numbers=[-1,0,9.2,0]
a=SparseVec(numbers)
print(a)
numbers2=[0,1,0,0,0]
b=SparseVec(numbers2)
print(b)
#Adds and merges values with keys in two dictionaries
def merged_dictionaries(a,b):
merged_dict={}
for key in a:
if key in b:
new_value=a[key]+b[key]
else:
new_value=a[key]
merged_dict[key]=new_value
for key in b:
if key not in merged_dict:
merged_dict[key]=b[key]
return merged_dict
c=merged_dictionaries(a,b)
for key, val in c.items(): # SparseVec iterator
print ('c[%d]=%g ' % (key,val))
print(c)
类方法(OOP)-(有缺陷的)
#Implements a Sparse vector (vector with many zero values) and adds two sparse vectors
class SparseVec:
#initializes the instance with given length
def __init__(self,length):
self.length=length
self.data={}
def __str__(self):
return 'Dense Vector {}'. format(self.data)
#Returns the length of the vector
def __len__(self):
return len(self.data)
# Returns nonzeros from the given(self) dictionary
def __getitem__(self, item):
return self.data
def __setitem__(self, key, val):
#To set a value by its key
self.data[key]= val
def nonzeros(self):
nonzerodict = {}
for key, val in enumerate(self):
if val:
nonzerodict[key] = val
return nonzerodict
def __add__(self, other):
c = {}
for key in self:
if key in other:
new_value = self[key]+ other[key]
else:
new_value = self[key]
c[key] = new_value
for key in other:
if key not in c:
c[key] = other[key]
return c
a = SparseVec(4)
a[2] = 9.2
a[0] = -1
print(a)
print(a.nonzeros())
b = SparseVec(5)
b[1] = 1
print(b.nonzeros())
c=a+b
print(c)
答案 0 :(得分:1)
您需要成对添加每个向量的成分,并返回一个SparseVector
对象:
class SparseVec:
def __init__(self, dimension):
self.dimension = dimension
self.data = {}
def __str__(self):
return 'Sparse Vector {}'. format(self.data)
def __len__(self):
return self.dimension # what matters is the size of the vector, not the length of the stored data
def __getitem__(self, key):
assert isinstance(key, int)
assert 0 <= key < self.dimension, 'the key must be compatible with the vector dimension'
try:
return self.data[key]
except KeyError:
return 0 # must return zero if valid key but no entry
def __setitem__(self, key, val):
assert isinstance(key, int)
assert 0 <= key < self.dimension, 'this vector does not have an appropriate dimension'
if val != 0: # avoid cluttering with zero values
self.data[key] = val
def purge_zeros(self): # <-- resparsifies a vector by purging the zero values
nonzerodict = {}
for key, val in self.data.items():
if val != 0:
nonzerodict[key] = val
self.data = nonzerodict
def __add__(self, other):
assert self.dimension == other.dimension, 'vectors must have the same dimension'
resulting_vector = SparseVec(self.dimension)
c = {k:v for k, v in self.data.items()} # <-- copies self data
for k, v in other.data.items():
try:
c[k] += v
except KeyError:
c[k] = v
resulting_vector.data = c
resulting_vector.purge_zeros()
return resulting_vector
a = SparseVec(4)
b = SparseVec(4)
a.data = {0: 2, 1: 1}
b.data = {0: -2, 1: 2, 2: 4}
print(a + b)
print(a[0], a[1], a[2], a[3])
print(b[0], b[1], b[2], b[3])
a[3] = -3
print(a[0], a[1], a[2], a[3])
Sparse Vector {1: 3, 2: 4}
2 1 0 0
-2 2 4 0
2 1 0 -3
答案 1 :(得分:0)
重载类方法实际上是编写通常由Python中的默认方法处理的方法,并用您自己的该类的方法替换它。
这是Python 3文档中的默认添加方法: https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types
我不确定您为什么要为此使用dict而不是没有更多上下文的列表,但是下面的方法应该起作用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static int[] groups = { 75, 40, 0 };
static void Main(string[] args)
{
int[] input = { 10, 3, 8, 23, 98, 34, 75, 23, 87, 56, 78 };
List<List<int>> results = input.GroupBy(x => GetGroup(x)).Select(x => x.ToList()).ToList();
}
static int GetGroup(int number)
{
int index = -1;
while (number < groups[++index]) ;
return index;
}
}
}
a是SparseVec类的实例,因此,为了访问 add 方法,我们调用a.add()并传入我们希望添加到其中的另一个对象。