Python:理解(如果(从g得到)和False,则为g in g)

Col*_*ole 20 python

詹姆斯鲍威尔在他即将发表的演讲的简短描述中表示,他是最狡猾的Python单线之一的自豪发明者:

(None for g in g if (yield from g) and False)
Run Code Online (Sandbox Code Playgroud)

我试图弄清楚这个生成器,因为我使用Python 2.7.x,我也绊倒了(yield from g)表达式.

我怎么读这个,什么是python 2.7.x模拟?


下面有一个很棒的讨论!我想检查一下我的主体是否正确.

>>> l = [10, 11, iter(xrange(5)), 12, 13]
>>> g = iter(l)
>>> flat_g = (None for g in g if (yield from g) and False)
>>> list(flat_g)
[10, 11, 0, 1, 2, 3, 4, 12, 13]
Run Code Online (Sandbox Code Playgroud)

那是对的吗?

Hyp*_*eus 10

这个表达似乎是一种代码高尔夫的写作方式:

(a for b in g for a in b)
Run Code Online (Sandbox Code Playgroud)

((或者也许动机是利用发电机代理,但恕我直言可读性确实受到影响.))

例如:

#! /usr/bin/python3.3

g = ['abc', 'def', 'ghi']

a = (None for g in g if (yield from g) and False)
for x in a: print (x)

b = (a for b in g for a in b)
for x in b: print (x)
Run Code Online (Sandbox Code Playgroud)

打印扁平列表的两倍.

我认为如果你使用不同的变量名,它会变得更加清晰:

(None for sublist in g if (yield from sublist) and False)
Run Code Online (Sandbox Code Playgroud)

哪个是一样的

(42 for sublist in g if (yield from sublist) and False)
Run Code Online (Sandbox Code Playgroud)

由于something and False外部生成器不产生任何东西,而内部生成器产生所有子列表的所有元素(子生成器,子数据).

也许这澄清了它的工作原理:

('Sublist {}'.format(idx) for idx, sublist in enumerate(g) if (yield from sublist) or True)
Run Code Online (Sandbox Code Playgroud)

显然原始的生成器可以简化为这个,省略了最后一个and False:

(None for sublist in g if (yield from sublist) )
Run Code Online (Sandbox Code Playgroud)

修订:

感谢的Martijn Pieters的打我的固执,我好不容易才看到,(None for sublist in g if (yield from sublist) and False)(None for sublist in g if (yield from sublist) )不等价的.这里有g一个与众不同的例子:

def f():
    yield 1
    return 2

def g():
    yield f()

a = (None for sublist in g() if (yield from sublist) )
for x in a: print(x)
a = (None for sublist in g() if (yield from sublist) and False)
for x in a: print(x)
Run Code Online (Sandbox Code Playgroud)

这打印:

1
None
1
Run Code Online (Sandbox Code Playgroud)

  • @thefourtheye看起来像.问题是,如果它没有"返回"任何东西,它为什么要评估任何真实的东西. (2认同)
  • @Hyperboreus:所以`def foo():产量1; 返回True`就是一个例子. (2认同)
  • @Hyperboreus:见http://docs.python.org/3/reference/expressions.html#yield-expressions;*当底层迭代器完成时,引发的`StopIteration`实例的value属性将成为yield表达式的值.它可以在引发`StopIteration`时显式设置,也可以在子迭代器是发生器时自动设置(通过从子发生器返回值).* (2认同)