(map vector '(1 2 3) '(4 5 6))
做你想要的事情:
=> ([1 4] [2 5] [3 6])
Haskell需要一系列zipWith
(zipWith3
, zipWith4
, ...) 函数,因为它们都需要特定的类型;特别地,它们接受的输入列表数目需要固定。(zip
、zip2
、zip3
、...等函数族可以被视为zipWith
函数族的一个特化,用于常见情况下的元组操作。)
相反,Clojure和其他Lisp方言对可变参数函数提供了良好的支持;map
是其中之一,并可以用于类似Haskell的"tupling"。
zipWith (\x y -> (x, y))
在Clojure中构建“元组”的惯用方式是构建一个短向量,如上所示。
(仅作完整性说明,注意Haskell使用一些基本扩展允许可变元数函数;但使用它们需要对语言有很好的理解,而vanilla Haskell 98可能根本不支持它们,因此固定元数函数更适用于标准库。)(partition 2 (interleave '(1 2 3) '(4 5 6)))
=> ((1 4) (2 5) (3 6))
或更普遍地说
(defn zip [& colls]
(partition (count colls) (apply interleave colls)))
(zip '( 1 2 3) '(4 5 6)) ;=> ((1 4) (2 5) (3 6))
(zip '( 1 2 3) '(4 5 6) '(2 4 8)) ;=> ((1 4 2) (2 5 4) (3 6 8))
(map vector [1 2 3] [4 5 6])
list
会给您一个类似于您示例中的列表列表。我认为很多Clojurians倾向于对此使用向量,虽然它可以与任何东西一起工作。而且输入不需要是相同的类型。map从它们创建序列,然后映射序列,因此任何可序列化输入都可以正常工作。(map list '(1 2 3) '(4 5 6))
(map list [1 2 3] '(4 5 6))
(map hash-map '(1 2 3) '(4 5 6))
(map hash-set '(1 2 3) '(4 5 6))
(interleave [1 2 3 4] [5 6 7 8]) => [1 5 2 6 3 7 4 8]
(partition 2 (interleave [1 2 3 4][5 6 7 8]))
。 - skuro有一个名为zipmap的函数,它可能具有类似的效果,
(zipmap (1 2 3)
(4 5 6))
输出如下:
{3 6, 2 5, 1 4}
(zipmap xs ys)
的“顺序”)。 - Reut Sharabani#(apply map list %)函数与Python的zip*函数一样,可以转置矩阵。作为宏定义:
用户=> (defmacro py-zip [lst] `(apply map list ~lst))
#'user/py-zip
用户=> (py-zip '((1 2 3 4) (9 9 9 9) (5 6 7 8)))
((1 9 5) (2 9 6) (3 9 7) (4 9 8))
用户=> (py-zip '((1 9 5) (2 9 6) (3 9 7) (4 9 8)))
((1 2 3 4) (9 9 9 9) (5 6 7 8))
zip
的行为不同。Ruby将继续处理,并为较短的集合提供nil
,而Clojure会在其中一个集合耗尽时停止处理。 - Nate W.zip
的行为与Clojure的map
类似。 - Michał Marczyk