<p>Python2:</p>
<pre><code>map(list, generator_of_generators)
</code></pre>
<p>Python3:</p>
<pre><code>list(map(list, generator_of_generators))
</code></pre>
<p>或者两者兼而有之:</p>
<pre><code>[list(gen) for gen in generator_of_generators]
</code></pre>
<hr/>
<p>因为生成的对象是<code>generator functions</code>,而不仅仅是生成器,所以您需要</p>
<pre><code>[list(gen()) for gen in generator_of_generator_functions]
</code></pre>
<p>如果那不起作用,我不知道你在问什么。另外,为什么它会返回一个生成器函数而不是生成器本身?</p>
<hr/>
<p>因为在评论中你说你想避免<code>list(generator_of_generator_functions)</code>神秘地崩溃,这取决于你真正想要的是什么。</p>
<ul>
<li><p>以这种方式覆盖<code>list</code>的行为是不可能的:要么存储子生成器元素,要么不存储子生成器元素</li>
<li><p>如果真的发生了崩溃,我建议每次主生成器迭代时都使用主生成器循环耗尽子生成器。这是标准实践,也正是<code>itertools.groupby</code>所做的,一个stdlib生成器。</p></li>
</ul>
<p>例如</p>
<pre><code>def metagen():
def innergen():
yield 1
yield 2
yield 3
for i in range(3):
r = innergen()
yield r
for _ in r: pass
</code></pre>
<ul>
<li>或者使用一个黑暗的,秘密的黑客方法,我会在一个mo(我需要写),但不要这样做!</li>
</ul>
<p>正如所承诺的,黑客(对于Python 3,这次是“回合”):</p>
<pre><code>from collections import UserList
from functools import partial
def objectitemcaller(key):
def inner(*args, **kwargs):
try:
return getattr(object, key)(*args, **kwargs)
except AttributeError:
return NotImplemented
return inner
class Listable(UserList):
def __init__(self, iterator):
self.iterator = iterator
self.iterated = False
def __iter__(self):
return self
def __next__(self):
self.iterated = True
return next(self.iterator)
def _to_list_hack(self):
self.data = list(self)
del self.iterated
del self.iterator
self.__class__ = UserList
for key in UserList.__dict__.keys() - Listable.__dict__.keys():
if key not in ["__class__", "__dict__", "__module__", "__subclasshook__"]:
setattr(Listable, key, objectitemcaller(key))
def metagen():
def innergen():
yield 1
yield 2
yield 3
for i in range(3):
r = Listable(innergen())
yield r
if not r.iterated:
r._to_list_hack()
else:
for item in r: pass
for item in metagen():
print(item)
print(list(item))
#>>> <Listable object at 0x7f46e4a4b850>
#>>> [1, 2, 3]
#>>> <Listable object at 0x7f46e4a4b950>
#>>> [1, 2, 3]
#>>> <Listable object at 0x7f46e4a4b990>
#>>> [1, 2, 3]
list(metagen())
#>>> [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
</code></pre>
<p>太糟糕了,我都不想解释。</p>
<p>关键是你有一个包装器,可以检测它是否已经被迭代,如果没有,你运行一个<code>_to_list_hack</code>,我不骗你,改变<code>__class__</code>属性。</p>
<p>由于布局冲突,我们必须使用<code>UserList</code>类并隐藏其所有方法,这只是crud的另一层。</p>
<p>基本上,请不要使用这个黑客。不过,你可以把它当作幽默来欣赏。</p>