0
$\begingroup$
For[i = 0, i < 4, i++, Print[i]]

gives the result:

0
1
2
3

by the definition of the If[] function. Given a much longer output of such values, how can I turn this into a list of form:

{0,1,2,3}

Ie I have an output of an If[] function that prints 100+ values that I want to be expressed in List[] form so I can manipulate the data.

$\endgroup$
  • 4
    $\begingroup$ Just use Table[i,{i,0,3}] or Range[0,3] instead of a For loop. This way there is no need to catch already Printed values after the fact. Instead Table or Range will already give you the result in List form and you can skip the Printing part entirely. In general just avoiding For loops is usually good advice. $\endgroup$ – Thies Heidecke Nov 6 '18 at 13:42
  • $\begingroup$ thanks @ThiesHeidecke will do! $\endgroup$ – beemen Nov 6 '18 at 13:46
1
$\begingroup$

If you want to use your code and not change many things, just use this instead of print

list = {};
For[i = 0, i < 4, i++, AppendTo[list, i]]
list
$\endgroup$
  • $\begingroup$ I'm not sure this is very good advice for a beginner. Better advice would go along the lines of (a) read mathematica.stackexchange.com/questions/134609/… and (b) don't use AppendTo to build lists incrementally unless there is absolutely no alternative. $\endgroup$ – High Performance Mark Nov 6 '18 at 13:54
  • $\begingroup$ I know what you mean... but this beginner may have many lines of code and he only wants to change print -> list. I'm sure that he read the other comment and prefer tables in the future. $\endgroup$ – J42161217 Nov 6 '18 at 14:01
3
$\begingroup$

As an extension of my comment here is an example what i think your program might look like and showing how you can write this without a For loop instead.

Selecting values

Let's say i want to generate every prime number between 0 and 100, i might go forth and write

For[i = 0, i < 100, i++,
  If[PrimeQ[i],
    Print[i]
  ]
]

2

3

...

This will print the desired result in single numbers in separate cells to the notebook, but it's hard to use in a future computation, where a list would be better.

A first step in that direction would be what J42161217 showed, which brings our code in this shape:

result = {};
For[i = 0, i < 100, i++,
  If[PrimeQ[i],
    AppendTo[result, i]
  ]
];
result

{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}

We added a bit of state (the variable result), but in exchange we got the result as a single list. Nice!

But we shouldn't stop here, since we can make this much simpler and faster! In this case we can start with all the values we want to try, which we can get with

Range[0,100]

{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ..., 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}

and only keep the ones which match our condition. This can be done with Select

Select[Range[0,100], PrimeQ]

{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}

This has quite a few advantages over the For-based solution we started with, namely:

  • We didn't need an extra result variable, so no additional unnecessary state
  • It's easier to see what this code wants to do: it generates the numbers from 0 to 100, and selects the ones which are prime, done!
  • It's faster, since Mathematica can loop over the values much more efficiently when we do operations on whole lists, than if we loop manually, where Mathematica has to do inefficient looping with an interpreter.
  • It's shorter, so it takes less time to read, less time to write, and less time to understand.

Applying the same function to different values

Via Mapping

Another use case instead of selecting parts of a list, where traditionally For loops are used, is applying the same function to different values. Let's say we want the first 100 square numbers. We can use the For solution from earlier, which would look like this:

result = {};
For[i = 0, i < 100, i++,
  AppendTo[result, i^2]
];
result

{0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, ..., 9409, 9604, 9801}

In this case we can achieve the same by Mapping the squaring function over the values:

Map[Function[i,i^2], Range[0, 100]]

or shorter

(#^2 &) /@ Range[0, 100]

where we used an anonymous function/lambda function (# is placeholder for the unnamed variable and & marks the end of the anonymous function) and /@ which is infix notation for Map, so f /@ values turns into Map[f,values].

Via Listable functions

In this case we can do even better because the operation we want to do (squaring a number via Power[#,2] & is Listable, which means, we can apply the function to list as we would apply it to a single value and Mathematica will efficiently iterate over those values in the list, but without us having to explicitly Map over the list:

(#^2 &)[Range[0, 100]]

or just

Range[0, 100]^2

will give us the same result as earlier.

The same advantages as for our other examples apply. I hope this gives you some motivation and curiosity to explore these different ways of thinking about your program and help you achieve what you want more easily.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.