考虑以下交互式示例
>>> l=imap(str,xrange(1,4))
>>> list(l)
['1', '2', '3']
>>> list(l)
[]
Run Code Online (Sandbox Code Playgroud)
有没有人知道是否已经在某处实现了一个版本的imap(和其他itertools函数),这样第二次执行列表(l)就会得到与第一次相同的结果.而且我不想要常规地图,因为如果使用更大的范围,在内存中构建整个输出可能会浪费内存.
我想要的东西基本上就像是
class cmap:
def __init__(self, function, *iterators):
self._function = function
self._iterators = iterators
def __iter__(self):
return itertools.imap(self._function, *self._iterators)
def __len__(self):
return min( map(len, self._iterators) )
Run Code Online (Sandbox Code Playgroud)
但如果有人已经这样做,那么对所有itertools手动执行此操作将是浪费时间.
PS.你认为容器比迭代器更禅,因为对于迭代器而言
for i in iterator:
do something
Run Code Online (Sandbox Code Playgroud)
当您明确需要删除元素的容器时,隐式清空迭代器.
您不必为每种类型的容器构建此类对象.基本上,您有以下内容:
mkimap = lambda: imap(str,xrange(1,4))
list(mkimap())
list(mkimap())
Run Code Online (Sandbox Code Playgroud)
现在你onlky需要一个漂亮的包装对象来防止"丑陋"的函数调用.这可以这样工作:
class MultiIter(object):
def __init__(self, f, *a, **k):
if a or k:
self.create = lambda: f(*a, **k)
else: # optimize
self.create = f
def __iter__(self):
return self.create()
l = MultiIter(lambda: imap(str, xrange(1,4)))
# or
l = MultiIter(imap, str, xrange(1,4))
# or even
@MultiIter
def l():
return imap(str, xrange(1,4))
# and then
print list(l)
print list(l)
Run Code Online (Sandbox Code Playgroud)
(未经测试,希望它有效,但你应该得到这个想法)
对于你的第二个问题:迭代器和容器都有它们的用途.你应该采取最符合你需求的东西.