蟒蛇2:
map(list, generator_of_generators)
蟒蛇 3:
list(map(list, generator_of_generators))
或两者兼而有之:
[list(gen) for gen in generator_of_generators]
由于生成的对象是generator functions
,而不仅仅是生成器,您想要这样做
[list(gen()) for gen in generator_of_generator_functions]
如果这不起作用,我不知道你在问什么。另外,为什么它会返回生成器函数而不是生成器本身?
由于在评论中你说你想避免list(generator_of_generator_functions)
神秘地崩溃,这取决于你真正想要什么。
例如。
def metagen():
def innergen():
yield 1
yield 2
yield 3
for i in range(3):
r = innergen()
yield r
for _ in r: pass
- 或者使用我将在稍后展示的黑暗的秘密黑客方法(我需要编写它),但不要这样做!
正如所承诺的那样,hack(对于 Python 3,这次是'round):
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]]
太糟糕了,我什至不想解释它。
关键是你有一个可以检测它是否被迭代的包装器,如果没有,你运行一个_to_list_hack
,我不骗你,改变__class__
属性。
由于布局冲突,我们必须使用UserList
类并隐藏它的所有方法,这只是另一层杂物。
基本上,请不要使用这个 hack。不过,你可以把它当作幽默来享受。