Python 增加列表嵌套级别的链接映射

Python 增加列表嵌套级别的链接映射,python,scheme,nested-loops,nested-lists,map-function,Python,Scheme,Nested Loops,Nested Lists,Map Function,我正在尝试执行以下Python到Scheme的转换,以练习嵌套循环: >>> def possible_triads(n1, n2, n3): for num1 in n1: for num2 in n2: for num3 in n3: print (num1, num2, num3) 以下是我在Scheme中的尝试: (define (possible-t

我正在尝试执行以下Python到Scheme的转换,以练习嵌套循环:

>>> def possible_triads(n1, n2, n3):
        for num1 in n1:
             for num2 in n2:
                 for num3 in n3:
                     print (num1, num2, num3)
以下是我在Scheme中的尝试:

(define (possible-triads n1 n2 n3)
  (map (lambda (num1)
         (map (lambda (num2)
                (map (lambda (num3) (list num1 num2 num3)) 
                     n3)) 
              n2)) 
       n1))
现在,很接近了,但我想知道为什么每个
映射都会产生一个新级别的列表?例如,如何使结果仅为三元组列表,例如:

(
    (1 3 5) 
    (1 3 6)
    (1 4 5)
    (1 4 6)
    (2 3 5)
    (2 3 6)
    (2 4 5)
    (2 4 6)
)

python
for
循环不会自动将其结果收集到
map
之类的列表中,因此您不会看到嵌套。每个
方案中的等效值为
,循环产生副作用,不收集结果。与Python函数一样,您应该在最内层循环中打印列表,而不是返回列表

(define (possible-triads n1 n2 n3)
  (for-each (lambda (num1)
    (for-each (lambda (num2)
      (for-each (lambda (num3) 
        (display (list num1 num2 num3))) n3)) n2)) n1))

通常,尝试从类似Algol的语言(如Python)中获取一些代码并将其“翻译”为lispy代码是一个坏主意。正如所提到的,Python代码并没有创建结果列表,它只是作为副作用打印结果;方案代码实际上正在创建一个结果列表。发布代码中的问题是,最里面的
map
创建列表列表,中间的
map
从中创建另一个列表列表,最外面的
map
从它接收的嵌套列表创建另一个列表列表

您可以通过战略性地附加映射操作的结果来实现这一点:

(定义(可能的空间坐标轴xs ys zs)
(应用附加)
(图(λ(x)
(应用附加)
(lambda(y)地图)
(地图(lambda(z)(列表x y z))
zs)
()
(xs))
在这里,
zs
上方最里面的
map
创建了一个列表列表。中间
map
使用该结果创建列表列表列表,并将其附加在一起以获得列表列表列表。最后,最外层的
map
使用内部两个映射操作提供的列表列表来创建另一个列表列表,并将其附加在一起以获得最终结果作为列表列表

注意,在这样的循环中使用
append
通常不是一个好主意;由于
append
本身具有线性时间复杂度,因此这些类型的解决方案往往是二次的或更糟的

nested looping.rkt>(可能的三元组’(12’(34’)(56))
'((1 3 5) (1 3 6) (1 4 5) (1 4 6) (2 3 5) (2 3 6) (2 4 5) (2 4 6))

map
列出其结果。Python版本没有在每一个级别上创建列表,只是进行迭代。Python版本没有将结果放在任何地方,只是进行打印。Scheme版本类似于Python中的嵌套列表理解。@Barmar所以我需要执行以下操作:
(set!L(append L(list(list numm1 numm2 num3))))
创建三元组列表?你应该为每个元组使用
,而不是
映射,然后在最里面的循环中使用
显示
。这种“通常不好的想法”(称为
flatMap
concatMap
等)是Haskell(等)“一元”处理列表(和其他事物)的基础其思想是,由于一个平面图保持列表深度不变,因此任何数量的平面图都会保持顺序不变。与嵌套循环(两个循环,一个在另一个内)产生的值与非嵌套循环产生的值相同,因此嵌套在另一个内的任意数量的循环(总深度为任意)最终都会依次产生结果。(从一个角度来看,这就是“monad”的全部含义)(从命令式程序员的角度来看,这就像什么都没说一样。)
(
    (1 3 5) 
    (1 3 6)
    (1 4 5)
    (1 4 6)
    (2 3 5)
    (2 3 6)
    (2 4 5)
    (2 4 6)
)
(define (possible-triads n1 n2 n3)
  (for-each (lambda (num1)
    (for-each (lambda (num2)
      (for-each (lambda (num3) 
        (display (list num1 num2 num3))) n3)) n2)) n1))