2010-04-13 57 views
2

我需要在同一時間返回兩個值,所以我有:如何遍歷實例對象的數據屬性,每次返回兩個值?

class IterableObject(object): 
    def __iter__(self): 
    for item in self.__dict__: 
     return self.__dict__[item + 1], self.__dict__[item] 

所以我可以有:

myObj1, myObj2 = IterableObject() 

value = myObj1.balance - myObj2.balance 

當然沒有奏效。我究竟做錯了什麼?我想我不能在這樣的項目上增加價值。

回答

5

itertools documentation有一個名爲pairwise一個例子的功能,可以複製到項目:

def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = tee(iterable) 
    next(b, None) 
    return izip(a, b) 

這樣使用它:

for x1, x2 in pairwise(some_iterable): 
    # etc.. 

注意,當我們通過遍歷dict項目不一定要按順序返回,所以你應該先排序。

+0

謝謝,但有沒有更簡單的方法來做到這一點,而無需走itertools的路線? – Spikie 2010-04-13 13:23:22

1

一個可能的解決方案,而itertools

def pairwise(iterable): 
    it = iter(iterable) 
    try: 
     while True: 
      yield it.next(), it.next() 
    catch StopIteration: 
     pass 

>>> list(pairwise(range(6)) 
[(0, 1), (2, 3), (4, 5)] 
>>> list(pairwise(range(5)) 
[(0, 1), (2, 3)] 

這是在這個意義上,如果它恰好包含奇數元素的最後一個項目是永遠不會從迭代器返回的itertools documentation的解決方案不同。但我想itertools例子中的解決方案更好。

1

對你自己的例子稍作修改應該會給你你想要的。 您的原始示例顯示您不知道迭代字典會爲您提供字典的鍵。 「aproprty_name」+ 1幾乎不會給你你想要的東西。

class IterableObject: 
    def __iter__(self): 
    properties = (i for i in self.__dict__) 
    While True: 
     a = properties.next() 
     try: 
     b = properties.next() 
     except StopIteration: 
     yield (getattr(self,a),) #for the odd number of properties case 
     raise StopIteration 
     yield getattr(self, a), getattr(self, b) 

這不適用於您提供的示例。你不能盲目地預期價值會以任何順序從另一個減去另一個的意義。

你可能想要的是一個對象,它從一個你知道是偶數個值的值列表中返回下一個值。您將不得不在對象中設置該列表。這樣,順序中的配對將以相同的順序傳回。

class PairedList: 
    def __iter__(self): 
    balances = iter(self.balances) 
    while True: 
     yield balances.next(), balances.next() 

>>> b = PairedList() 
>>> b.balances = (2000, 151, 1000, 255, 600, 150, 0, 20, 30, 30, 50, 10) 
>>> [i for i in b] 
[(2000, 151), (1000, 255), (600, 150), (0, 20), (30, 30), (50, 10)] 
>>> [(balance-withdrawal, balance, withdrawal) for balance, withdrawal in b] 
[(1849, 2000, 151), (745, 1000, 255), (450, 600, 150), (-20, 0, 20), (0, 30, 30), (40, 50, 10)] 

你可能想重讀你的問題和榜樣,重新改寫問題,因爲寫你正在創建一個新的對象,並期待它已經包含了你的價值觀。使用我PairedList類,願意爲你做這方面的一個例子是:

>>> PairedList.balances = b.balances 
>>> [(balance-withdrawal, balance, withdrawal) for balance, withdrawal in PairedList()] 
[(1849, 2000, 151), (745, 1000, 255), (450, 600, 150), (-20, 0, 20), (0, 30, 30), (40, 50, 10)] 

但是,這是幾乎可以肯定不是你想要的。它會默認限制你只有一組餘額可以迭代。並且會爲每個PairedList對象創建一個默認的餘額設置,最終會讓您再次陷入困境。

相關問題