容器的Itertools

M.D*_*.D. 9 python iterator

考虑以下交互式示例

>>> 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)

当您明确需要删除元素的容器时,隐式清空迭代器.

glg*_*lgl 7

您不必为每种类型的容器构建此类对象.基本上,您有以下内容:

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)

(未经测试,希望它有效,但你应该得到这个想法)

对于你的第二个问题:迭代器和容器都有它们的用途.你应该采取最符合你需求的东西.