Mathematica优化AppendTo–Reap&Sow

  • A+
所属分类:Wolfram语言进阶
摘要这一篇会叙述一下mathematica中Reap和Sow两个函数的使用方法。也是给出一种方便快速往列表里增加值的方法。

在我们日常使用过程中,我们经常需要动态的修改一些列表,学过数据结构的话都知道,如果按顺序存储,那么当列表满了再往里面增加元素是需要再重新新建一个列表的,这个就会导致程序速度变慢,那么在Mathematica中有什么可以解决这个问题的方法呢,答案就是使用ReapSow

其实之前我们也讲过关于ReapSow的一些用法,可以看下面这篇文章,Mathematica入门习题[4]–Reap与Sow的使用和字符串匹配,这一篇文章我们再详细说明一下ReapSow的一些用法。

关于详细的资料,可以在Mathematica的帮助文档中搜索:tutorial/CollectingExpressionsDuringEvaluation

Reap&Sow基本用法

其实Reap和Sow是用来收集计算过程中的一些数字的,Reap是用来收集计算过程中Sow的值的,我们可以看一下下面的这个例子:

Reap[Sow[a = 3]; a += Sow[a^2 + 1]; Sow[a]; a = Sqrt[a + a^2]]
>> {Sqrt[182], {{3, 10, 13}}}

计算过程中Sow了两次,Reap就都能收集到,最后一个没有写Sow是因为Reap能计算那个表达式的值。

Reap&Sow与AppendTo对比

之前说过使用ReapSow会比使用AppendTo速度要快,我们在这里做一个小的测试--获取0-10^7之间所有被133整除的数字,我们分别使用两种方法来实现。

Reap&Sow

Timing[
 Reap[
  Do[(If[Mod[i, 133] == 0, Sow[i]]), {i, 1, 10^7}]
  ]
 ]

这里一共花费了8s的时间,我们看一下AppendTo需要多久。

AppendTo

Timing[
 t = {};
 Do[
  (If[Mod[i, 133] == 0, AppendTo[t, i]]), {i, 1, 10^7}
  ];
 t
 ]

可以看到,使用AppendTo的话需要40+s的时间,比上面的方法是要慢很多的,

其实,除了上面的方法,我们还可以使用Select的方法

Timing[Select[Range[1, 10^7], Mod[#, 133] == 0 &]]

可以看到时间也是8s多,也是挺不错的。

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: