如何解压缩对象,因为它是for循环中的元组?

use*_*ser 2 python iterator generator iterable-unpacking python-3.6

我尝试创建以下代码:

class Test(object):

    def __init__(self, arg):
        self.arg1 = arg + 1
        self.arg2 = arg + 2
        self.arg3 = arg + 3

    def __iter__(self):
        return self

    def __next__(self):
        yield self.arg1, self.arg2, self.arg3


test_list = [Test(0), Test(1), Test(2)]

for arg1, arg2, arg3 in test_list:
    print('arg1', arg1, 'arg2', arg2, 'arg3', arg3)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试运行时,python说:

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    for arg1, arg2, arg3 in test_list:
ValueError: too many values to unpack (expected 3)
Run Code Online (Sandbox Code Playgroud)

我可以通过手工拆包来解决它:

class Test(object):

    def __init__(self, arg):
        self.arg1 = arg + 1
        self.arg2 = arg + 2
        self.arg3 = arg + 3

test_list = [Test(0), Test(1), Test(2)]

for test in test_list:
    arg1, arg2, arg3 = test.arg1, test.arg2, test.arg3
    print('arg1', arg1, 'arg2', arg2, 'arg3', arg3)
Run Code Online (Sandbox Code Playgroud)

我们怎样才能解析python列表中的对象而不用显式解决方法呢?对于最后一个示例,结果如下:

arg1 1 arg2 2 arg3 3
arg1 2 arg2 3 arg3 4
arg1 3 arg2 4 arg3 5
Run Code Online (Sandbox Code Playgroud)

Aja*_*234 7

您很接近,但是,您需要方法中yield的值__iter__,而不是__next__方法:

class Test:
  def __init__(self, arg):
    self.arg1 = arg + 1
    self.arg2 = arg + 2
    self.arg3 = arg + 3
  def __iter__(self):
    yield from [self.arg1, self.arg2, self.arg3]

for a, b, c in [Test(0), Test(1), Test(2)]:
  pass
Run Code Online (Sandbox Code Playgroud)

yield self.arg1, self.arg2, self.arg3将给出一个tuple结果(1, 2, 3),当迭代列表时,需要额外的解包,即:

for [(a, b, c)] in [Test(0), Test(1), Test(2)]:
  pass
Run Code Online (Sandbox Code Playgroud)

因此,为了避免循环中的额外解包,您必须通过遍历属性并一次产生一个来创建生成值流。


Ara*_*Fey 6

问题是您的__next__方法没有正确实现.您使Test该类可迭代,但它不会迭代您的想法:

>>> itr = iter(Test(0))
>>> next(itr)
<generator object Test.__next__ at 0x7ff609ade9a8>
>>> next(itr)
<generator object Test.__next__ at 0x7ff609ade930>
>>> next(itr)
<generator object Test.__next__ at 0x7ff609ade9a8>
Run Code Online (Sandbox Code Playgroud)

它不是产生一个(self.arg1, self.arg2, self.arg3)元组,而是产生生成器.这是由于您yield__next__方法内部的使用造成的.一个__next__方法应该返回值,而不是屈服他们.请参阅此问题以获取详细说明和解决方法.