Monday, December 28, 2015

How can I avoid using a For-loop in my code? – mathematica.stackexchange.com #JHedzWorlD


I am trying to avoid using For because I heard that For is not cool in functional programming. Below is a problem that the first idea came to my mind is using For. How can I change this into a code using Table or Range or something else?


What the code does is to extract the elements in a list ls which satisfies certain condition into a new list lsNew.


ls = RandomInteger[20, 1000]; lsNew = ; For[i = 1, i <= Length[ls], i++, If[ls[[i]] < 6, lsNew = Append[lsNew, ls[[i]]]]] lsNew 



Have a look at Select.


lsNew = Select[# < 6 &]@ls 



OK, the related post I linked above may be too long, so let me extract the relevant part:


Pick[#, UnitStep[# - 6], 0] &@ls 

Just for fun, here’s a somewhat strange solution:


ls /. $_ /; $ >= 6 :> (## &[]) 



Although Select is the classical Mathematica function for doing what you ask, in V10.2 or later one can map an If expression (for some a more natural way to express the problem) and get the desired results.


SeedRandom[42]; data = RandomInteger[20, 100]; If[# < 6, #, Nothing] & /@ data 

4, 2, 1, 0, 4, 3, 0, 1, 4, 2, 5, 5, 3, 1, 2, 1, 1, 1, 2, 4, 5, 0, 5, 3, 1, 0, 3, 4, 5, 3, 5



This is likely to run slower the Select, but will run much faster than a For-loop.











    

Use Select instead. The setup is much, much simpler, and it doesn't use $O(n^2)$ methods to do it. (Append used like this is the culprit.) – rcollyer 3 hours ago




    

















1  

One can still use If to solve the problem before v10.2, by using these instead of Nothing :). – xzczd 1 hour ago


JHedzWorlD


AIM GLOBAL






No comments:

Post a Comment