2015-09-06 82 views
4

我想創建一個方法(總和),需要可變數量的向量,並將它們添加進來。爲了教育目的,我寫了我自己的Vector類,並且底層數據是存儲在名爲data的實例變量中。Pythonic的方式添加一個列表

我的代碼爲@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) 
+2

http://codereview.stackexchange.com –

+0

爲什麼一個類的方法? – msw

+0

我在想,總和應該返回一個新的向量,因此使用了一個類的方法。 –

回答

6

itertools.izip_longest可能會在您的情況非常方便:

a = [1, 2, 3, 4] 
b = [1, 2, 3, 4, 5, 6] 
c = [1, 2] 

lists = (a, b, c) 

result = [sum(el) for el in itertools.izip_longest(*lists, fillvalue=0)] 

在這裏,你得到了你想要的東西:

>>> 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)] 

所以,如果你運行一個列表理解,總結了所有的子元素,你會得到你的結果。

+0

謝謝,這個作品! –

2
args = [[1, 2, 3], 
     [10, 20, 30], 
     [7, 3, 15]] 

result = [sum(data) for data in zip(*args)] 
# [18, 25, 48] 

這是你想要的嗎?

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 

在這裏,我還實施了另外的Vectorint,加入了「反向加入」 __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]) 
+0

謝謝你,我沒有考慮這種方法,並學到了新的東西! –

相關問題