简体   繁体   English

如何遍历实例对象的数据属性,一次返回两个值?

[英]How to iterate over an instance object's data attributes, returning two values at a time?

I need to return two values at a time, so I have: 我需要一次返回两个值,所以我有:

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

So I can have: 所以我可以有:

myObj1, myObj2 = IterableObject()

value = myObj1.balance - myObj2.balance

Of course it did not work. 当然没有用。 What am I doing wrong? 我究竟做错了什么? I think I can not add value on item like that. 我想我无法在这样的项目上增加价值。

In the itertools documentation there is an example function called pairwise that you can copy into your project: itertools文档有一个叫做例子功能pairwise ,你可以复制到你的项目:

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

Use it like: 像这样使用它:

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

Note that when you iterate over a dict the items are not necessarily returned in order, so you should sort first. 请注意,当您遍历dict ,不一定按顺序返回项目,因此应首先进行排序。

A possible solution without itertools : 没有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)]

This is different from the solution in the itertools documentation in the sense that the last item is never returned from the iterable if it happens to contain an odd number of elements. 这与itertools文档中的解决方案的不同之处在于,如果最后一项恰好包含奇数个元素,则永远不会从iterable中返回。 But I guess the solution in the itertools examples is better. 但是我猜itertools示例中的解决方案更好。

A slight modification to your own example should give you what you want. 对您自己的示例进行稍作修改即可为您提供所需的内容。 Your original example shows that you don't know that iterating over a dictionary gives you the keys of the dictionary. 您的原始示例表明,您不知道迭代字典会给您字典的键。 "aproprty_name" + 1 will almost never give you what you want. “ 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)

This will not work in the example you present. 在您提供的示例中,这将不起作用。 You can not blindly anticipate the values being in any order that would make subtracting one from the other make sense. 您不能盲目地期望以任何顺序减去彼此有意义的值。

What you probably want is an object that returns the next two values from a list of values that you know to be an even number of values. 您可能想要的是一个对象,该对象从您知道是偶数个值的值列表中返回下两个值。 You will have to set that list in the object. 您将必须在对象中设置该列表。 That way the paired in order sequence would be passed back in the same order. 这样,成对的顺序序列将以相同的顺序传回。

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

You might want to reread you question and example and rephrase them because as written you are creating a new object and expecting it to already contain your values. 您可能想重新阅读问题和示例并重新措辞,因为在撰写本文时,您正在创建一个新对象并期望它已经包含您的值。 An example using my PairedList class that would do this for you would be: 使用我的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)]

But this is almost certainly not what you want. 但这几乎可以肯定不是您想要的。 It would by default limit you to only ever having one set of balances that you could iterate over. 默认情况下,它将限制您只能使用一组可以迭代的余额。 And would create a default set of balances for every PairedList object which will eventually come back to bite you in the butt. 并会为每个PairedList对象创建一组默认的余额,这些余额最终会再次吸引您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM