相当于Mathematica的List-comprehension中的Python&Zip?

时间:2014-09-22 22:52:18

标签: python functional-programming zip wolfram-mathematica list-comprehension

Mathematica.SE中的人显然有一个Python-phobia here所以我在这里问:在Mathematica的列表理解中,什么等同于Python的ZIP?

的Python

>>> [(ii,jj) for (ii,jj) in zip((1,10,100),(2,20,200))]
[(1, 2), (10, 20), (100, 200)]
>>> [(ii,jj,kk) for (ii,jj,kk) in zip((1,10,100),(2,20,200),(3,30,300))]
[(1, 2, 3), (10, 20, 30), (100, 200, 300)]

数学吗

  1. Thread[Times[{1, 11}, {2, 22}]]有点相似但不等同(失败?)
  2. 其他方法?

3 个答案:

答案 0 :(得分:3)

如果您只想重新安排示例中指定的元素,那么@Alan会有正确的答案。在更一般的意义上,Pythons列表推导等同于其他语言称为“map”和“filter”,尽管在你的情况下你似乎没有使用任何过滤器。 问题可分为两个步骤:

  1. 压缩某些列表中的元素。
  2. 从这个新列表中创建一个新列表。
  3. 因此除了transpose之外,您可能还想使用Map函数。这是一个例子:

    PythonZipMap[func_, list_List] := Map[func, Transpose[list]];
    

    此函数首先执行列表的“zip”,然后将表达式应用于每个条目。

    list = {{1, 2, 3}, {10, 20, 30}, {100, 200, 300}};
    PythonZipMap[Identity, list]
    {{1, 10, 100}, {2, 20, 200}, {3, 30, 300}}
    PythonZipMap[Total, list]
    {111, 222, 333}
    PythonZipMap[Median, list]
    {10, 20, 30}   
    

    我真的只是从Mathematica开始,所以我确信其他人会有更好的答案。

    ---更新---

    如果生成的压缩列表元素应作为输入传递给您的函数,您也可以使用MapThread。例如,上面的Total可以像这样实现:

    MapThread[Plus, list]
    {111, 222, 333}
    

答案 1 :(得分:0)

Python 2还是Python 3? Python 2实际上创建了这些对象,在这种情况下等效似乎

Transpose@{{1, 10, 100}, {2, 20, 200}}
Transpose@{{1, 10, 100}, {2, 20, 200}, {3, 30, 300}}

这忽略了非矩形的情况,因为你的例子没有提出这个问题。

答案 2 :(得分:0)

zip[{} ..] := {};
zip [p : xs__] /; MemberQ[{p}, {}] := {};
zip[p : Repeated[_List, {2, \[Infinity]}]] := Join[Through[{Apply[First[{#}]&,
{##}, {1}]&}[p]], zip[(Rest[{##1}] & @@@ {p}) /. {x__List} :> Sequence[x]]]

使用不同长度的列表:

zip[{1, 2, 3}, {4, 5, 6}, {7, 8}, {10, 11, 12}]
(* {{1, 4, 7, 10}, {2, 5, 8, 11}} *)

使用相同长度的列表:

zip[{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}]
(* {{1, 4, 7, 10}, {2, 5, 8, 11}, {3, 6, 9, 12}} *)