Python 如何迭代实例对象';s数据属性,一次返回两个值?

Python 如何迭代实例对象';s数据属性,一次返回两个值?,python,iterator,Python,Iterator,我需要一次返回两个值,因此我有: 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 当然没有用。

我需要一次返回两个值,因此我有:

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
当然没有用。我做错了什么?我想我不能为这样的项目增加价值。

中有一个名为
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
时,项目不一定按顺序返回,因此您应该首先排序。

不使用
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)]

这与解决方案的不同之处在于,如果iterable恰好包含奇数个元素,则最后一项永远不会从iterable返回。但是我想,
itertools
示例中的解决方案更好。

对您自己的示例稍加修改就可以满足您的需求。 您的原始示例表明,您不知道迭代字典会得到字典的键。“恰当的名字”+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)]
您可能想重读您的问题和示例,并重新表述它们,因为编写时您正在创建一个新对象,并希望它已经包含您的值。使用my 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对象创建一组默认的平衡,这些对象最终会回来咬你的屁股。

谢谢,但是有没有一种更简单的方法可以做到这一点而不必使用itertools?