使用应用于每个元素的操作创建新列表?

时间:2012-09-11 15:46:06

标签: wolfram-mathematica

我有一个包含元素的列表:

  

数据= {{1,2},{2,7},{3,14}}

这是X和Y坐标的列表,稍后用于ListPlot。

对于所有Y坐标,我基本上想要做Y = 1 / Y,所以新的列表变为:

  

DataNew = {{1,1 / 2},{2,1 / 7},{3,1 / 14}}

我该怎么做?

3 个答案:

答案 0 :(得分:6)

使用data = {{1, 2}, {2, 7}, {3, 14}}我建议:

{#, 1/#2} & @@@ data

或者你可以使用:

Replace[data, {x_, y_} :> {x, 1/y}, {1}]

我建议不要使用以下任何一种:

data /. {x_, y_} -> {x, 1/y}

Cases[data, {x_, y_} -> {x, 1/y}]

两者都错误地使用Rule而不是RuleDelayed,这意味着它们无法本地化命名模式。此外,第一个并不好,因为它引入了歧义:

{{1, 2}, {2, 7}} /. {x_, y_} :> {x, 1/y}
{{1, 2}, {1/2, 1/7}}

第二个问题不那么麻烦,但恕我直言,因为Cases是一个过滤功能,所以不应该在你真正需要Replace的地方使用它,因为这会使代码不那么清晰。


Leonid提醒我们,我推荐的方法不会在可能的情况下自动编译(例如Reals的打包数组)。如果性能至关重要,那么使用下面比较的双Transpose方法通常最快。

dat = RandomReal[99, {50000, 2}];

Do[ {#, 1/#2} & @@@ dat , {50}] // Timing

Do[ Transpose[{#, 1/#2} & @@ Transpose@dat] , {50}] // Timing
  

{2.074,Null}

     

{0.032,Null}

答案 1 :(得分:5)

您可以使用:

{#[[1]], 1/#[[2]]} & /@ Data

答案 2 :(得分:3)

另外例如:

data = {{1, 2}, {2, 7}, {3, 14}};
newData = data /. {x_, y_} -> {x, 1/y}

newData = Cases[data, {x_, y_} -> {x, 1/y}]

f[{a_, b_}] := {a, 1/b};
newData = f /@ data

以及其他各种可能性。

请记住以小写字母开始所有已定义的名称!