为什么对可迭代对象进行映射会返回一次性可迭代对象?

Man*_*idt 3 python iteration iterator python-3.x

为什么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
Run Code Online (Sandbox Code Playgroud)

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

编辑: 这是一个恕我直言应该如何工作的示例,演示了惰性评估:

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
Run Code Online (Sandbox Code Playgroud)

use*_*ica 5

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

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

此外,随着重复迭代,需要重复函数求值或缓存结果(但如果要缓存结果,为什么要重新设计map以返回迭代器呢?)。重复的功能评估效率低下,有潜在危险,而且通常不是用户想要的。最好让用户显式重复map调用,或者list如果他们想再次迭代则显式调用。

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