我正在尝试创建一个方法(sum),它采用可变数量的向量并将它们添加进去。出于教育目的,我编写了自己的Vector
类,并且底层数据存储在一个实例中变量命名数据。
我的@classmethod
和的代码有效(对于传入的每个向量,循环遍历数据变量中的每个元素并将其添加到结果列表中),但它似乎是非Pythonic,并且想知道是否有更好的方法吗?
class Vector(object):
def __init__(self, data):
self.data = data
@classmethod
def sum(cls, *args):
result = [0 for _ in range(len(args[0].data))]
for v in args:
if len(v.data) != len(result): raise
for i, element in enumerate(v.data):
result[i] += element
return cls(result)
答案 0 :(得分:6)
itertools.izip_longest
可能非常方便:
>>> result
[3, 6, 6, 8, 5, 6]
在这里你得到了你想要的东西:
0
它的功能就是将空值与izip_longest(a, b)
一起填充,从而简单地将您的列表压缩在一起。例如[(1, 1), (2, 2), (3, 0), (4, 0)]
将是>>> lists
([1, 2, 3, 4], [1, 2, 3, 4, 5, 6], [1, 2])
>>> list(itertools.izip_longest(*lists, fillvalue=0))
[(1, 1, 1), (2, 2, 2), (3, 3, 0), (4, 4, 0), (0, 5, 0), (0, 6, 0)]
。然后只是总结中间列表的每个元组元素中的所有值。
所以这里你一步一步走:
range()
因此,如果您运行列表推导,总结所有子元素,您将获得结果。
答案 1 :(得分:5)
您可以做的另一件事(可能更多" pythonic")将是__add__
magic method的实施,因此您可以使用+
和sum
直接在矢量上。
class Vector(object):
def __init__(self, data):
self.data = data
def __add__(self, other):
if isinstance(other, Vector):
return Vector([s + o for s, o in zip(self.data, other.data)])
if isinstance(other, int):
return Vector([s + other for s in self.data])
raise TypeError("can not add %s to vector" % other)
def __radd__(self, other):
return self.__add__(other)
def __repr__(self):
return "Vector(%r)" % self.data
在这里,我还实现了Vector
和int
的添加,在每个Vector的数据元素上添加了数字,以及"反向添加" __radd__
,以使sum
正常工作。
示例:
>>> v1 = Vector([1,2,3])
>>> v2 = Vector([4,5,6])
>>> v3 = Vector([7,8,9])
>>> v1 + v2 + v3
Vector([12, 15, 18])
>>> sum([v1,v2,v3])
Vector([12, 15, 18])
答案 2 :(得分:2)
args = [[1, 2, 3],
[10, 20, 30],
[7, 3, 15]]
result = [sum(data) for data in zip(*args)]
# [18, 25, 48]
这是你想要的吗?