为什么Scheme中生成数对的get-pairs函数迭代输出首元素是空列表
问题1:为什么输出第一个元素是'()
你的猜测完全正确,就是i=1的场景导致的:
- 外层
map遍历的是(range 1 n),第一个迭代的元素就是i=1 - 内层给
j生成取值范围的代码是(range 1 (- i 1)),代入i=1就是(range 1 0),根据你定义的range函数逻辑,a > b时返回空列表nil - 内层
map对空列表做映射,返回结果就是空列表,所以外层map的第一个返回值就是空列表,也就是你看到的输出开头的'()
问题2:对空列表执行map返回空列表是不是Scheme固有特性?
是,这是Scheme标准明确定义的行为,几乎所有函数式语言的map实现都遵循这个逻辑:map的作用是将传入的函数依次应用到输入列表的每一个元素,再把所有返回值按顺序组成新列表。如果输入列表本身是空的,没有元素可以应用函数,自然返回空列表。
怎么改才能得到和Python示例一致的输出?
你现在的代码用两层map会返回嵌套结构,只要把外层的map换成append-map(部分Scheme实现中叫flatmap),就会自动把内层列表平铺,空列表会在拼接的时候自动被忽略:
; 修改后的get-pairs,返回平铺的数对列表 (define (get-pairs n) (append-map (lambda (i) (map (lambda (j) (list i j)) (range 1 (- i 1)))) (range 1 n)))
调用(get-pairs 3)就会得到((2 1) (3 1) (3 2)),和Python示例的输出逻辑完全一致。
另外注意:你代码注释标注的生成规则是1 <= i < j <= N,但当前实现生成的是j < i的数对,如果要符合注释的规则,把j的取值范围改成(range (+ i 1) n)即可。
内容的提问来源于stack exchange,提问作者David542
相关产品推荐
相关产品推荐

