在 python 中尝试函数式编程时,我注意到两个表达式之间的差异,我认为应该有相同的结果。
特别是我想要的是拥有一个由(或者我应该说产生?)其他可迭代对象组成的可迭代对象。我想做的一个简单示例可能是:
import itertools as itr
itr.repeat(itr.repeat(1,5),3)
这是一个由 3 个可迭代对象组成的可迭代对象,它们本身由数字 1 的 5 次出现组成。然而,事实并非如此。我得到的(翻译成列表)是:
[[1,1,1,1,1],[],[]]
也就是说,最里面的可迭代对象没有被复制(看起来),而是同一个可迭代对象被一次又一次地使用,导致元素用完。
一个使用 map 的版本是:
import itertools as itr
map(lambda x: itr.repeat(1,5), range(3))
这会产生我期望的结果:
[[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1]]
我不明白为什么这行得通,而仅使用 repeat 的方法却行不通。也许这与 map 版本中的事实有关,来自 repeat 的可迭代对象被包装在 lambda 中,但这应该有所作为吗?据我所知,lambda x: itr.repeat(1,5) 和 itr.repeat(1,5) 之间的唯一区别是第一个接收一个参数(然后将其丢弃),而另一个不接收。
请您参考如下方法:
如您所述,itertools.repeat() 不会复制重复的项目,而是每次都使用相同的可迭代对象。
map() 方法之所以有效,是因为 lambda 函数针对 range(3) 中的每个元素单独调用,因此您会得到三个单独的 itertools.repeat (1, 5) 可迭代以生成嵌套内容。
要完全使用 itertools 完成此操作,您可以使用 itertools.tee :
import itertools as itr
itr.tee(itr.repeat(1, 5), 3)
这是一个将结果显示为列表的示例:
>>> [list(x) for x in itr.tee(itr.repeat(1, 5), 3)]
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
