容器的Itertools

时间:2011-08-14 22:42:58

标签: iterator python

考虑以下交互式示例

>>> l=imap(str,xrange(1,4))
>>> list(l)
['1', '2', '3']
>>> list(l)
[]

有没有人知道是否已经在某处实现了一个版本的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) )

但如果有人已经这样做,那么对所有itertools手动执行此操作将是浪费时间。

PS。 你认为容器比迭代器更禅,因为对于像

这样的迭代器
for i in iterator:
    do something

在明确需要删除元素的容器时隐式清空迭代器。

3 个答案:

答案 0 :(得分:7)

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

mkimap = lambda: imap(str,xrange(1,4))
list(mkimap())
list(mkimap())

现在你需要一个很好的包装对象来防止“丑陋”的函数调用。这可以这样工作:

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)

(未经测试,希望它有效,但你应该明白这一点)

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

答案 1 :(得分:1)

您可能正在寻找itertools.tee()

答案 2 :(得分:-1)

迭代器是我最喜欢的主题;)

from itertools import imap

class imap2(object):
    def __init__(self, f, *args):
        self.g = imap(f,*args)
        self.lst = []
        self.done = False

    def __iter__(self):
        while True:
            try: # try to get something from g
                x = next(self.g)
            except StopIteration:
                if self.done:
                    # give the old values
                    for x in self.lst:
                        yield x
                else:
                    # g was consumed for the first time
                    self.done = True
                return
            else:
                self.lst.append(x)
                yield x




l=imap2(str,xrange(1,4))
print list(l)
print list(l)