为什么map over a iterable会返回一次性迭代?

时间:2017-03-31 06:45:21

标签: python python-3.x iterator iteration

为什么map在使用可以多次迭代的对象调用时不会返回一个也可以多次迭代的对象?我认为后者更合理。

我的用例是我有很多data,因此它只能被迭代。 map(理论上)完美适用于data上的操作,因为它是懒惰的。但是在下面的例子中,我希望长度都是相同的。

iterable = [1,2,3,4]  # this can be iterated repeatedly
m = map(lambda x:x**2, iterable) # this again should be iterable repeatedly
print(len(list(m))) # 4
print(len(list(m))) # 0

如何映射可迭代结构并获得可迭代结构?

修改 这是一个如何工作的例子,展示了懒惰的评价:

def g(): 
    print('g() called')

data = [g, g]

# map is lazy, so nothing is called
m = map(lambda g: g(), data)
print('m: %s' % len(list(m))) # g() is called here
print('m: %s' % len(list(m))) # this should work, but doesnt

# this imap returns an iterable
class imap(object):
    def __init__(self, fnc, iterable):
        self.fnc = fnc
        self.iterable = iterable
    def __iter__(self):
        return map(self.fnc, self.iterable)

# imap is lazy, so nothing is called
im = imap(lambda g: g(), data)    
print('im: %s' % len(list(im))) # g() is called here
print('im: %s' % len(list(im))) # works as expected

1 个答案:

答案 0 :(得分:4)

  

为什么使用可以多次迭代的对象调用map时不会返回一个也可以多次迭代的对象?

因为告诉没有接口是否可以重复迭代对象。 map无法判断它迭代的内容是否支持重复迭代,除非map设法以某种方式确定此信息并发明API以将其公开给其用户,map个用户无法判断他们的map对象是否支持重复迭代。

此外,重复迭代需要重复函数评估或缓存结果(但如果要缓存结果,为什么要重新设计map以返回迭代器?)。重复的功能评估效率低下,潜在危险,通常不是用户想要的。如果用户想要再次进行迭代,最好让用户明确重复map调用或明确调用list

如果map对象总是只是迭代器,那就更简单了。