考虑以下交互式示例
>>> l=imap(str,xrange(1,4))
>>> list(l)
['1', '2', '3']
>>> list(l)
[]有没有人知道在某个地方已经有一个imap版本的实现(和其他itertools函数),这样第二个time list(l)就会被执行,你会得到和第一个一样的结果。我不想要常规的map,因为如果您使用更大的范围,在内存中构建整个输出可能是对内存的浪费。
我想要的东西基本上是这样的
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隐式清空迭代器,而容器需要显式删除元素。
发布于 2011-08-15 06:52:51
您不必为每种类型的容器构建这样的对象。基本上,您拥有以下内容:
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)(未经测试,希望它能工作,但你应该明白这个想法)
关于你的第二个问题:迭代器和容器都有它们的用途。你应该选择最适合你需要的东西。
发布于 2011-08-15 06:52:05
您可能正在寻找itertools.tee()
发布于 2011-08-15 09:17:23
迭代器是我最喜欢的话题;)
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)https://stackoverflow.com/questions/7060229
复制相似问题