Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have written a For loop in my Mathematica notebook. This For loop, when activated, will generate a sequence something like:

    0.1
    Null
    0.3
    0.4
    Null
    0.6

etc. The output solely consists of numbers and nulls.

What I want to do is plot these values generated by my For loop, using ListPlot. However, to use ListPlot I must first have a list, and the output of my For loop isn't in the form a list. How can I convert the output of my For loop into a list?

(Note: My For loop generates a large amount of numbers, so it is too laborious to manually enter these values into a list one by one).

My For loop is:

    For[i = 0,  i <1000,  i++,
       Print[
             For[n = 100, n < 600, n++,
                If[Abs[Nest[f, i*StepSize1, n] - 0.51304]<0.0001, 
                   {Print[i* StepSize1], Break[]}, {Indeterminate, Break[]}]
                ] 
            ]
      ]

StepSize is pre-defined, by the way.

share|improve this question
1  
Have a look at Map. –  b.gatessucks Nov 9 '12 at 19:45
1  
You have a whole set of tools in Mma to avoid using For[]loops. Consider them as a last resource. –  belisarius Nov 9 '12 at 19:48
6  
The first rule about using For loops in Mathematica is that you don't use For loops =) –  rm -rf Nov 9 '12 at 19:52
3  
The second rule about using For loops in Mathematica is that you do not use For loops ;-) –  Chris Degnen Nov 9 '12 at 20:33

3 Answers 3

up vote 7 down vote accepted

One thing to keep in mind about loops: For doesn't localize its iterator, while Do does. Thus, it's usually better to use Do to avoid problem (eg when using i as an iterator and calling a function that also uses i internally without localizing it). To build up the list, one can use Sow and Reap. Thus:

Do[Sow[5 + i], {i, 1, 10}] // Reap // Last // Last
(*{6, 7, 8, 9, 10, 11, 12, 13, 14, 15}*)

Here's what I mean by localizing. Compare:

ClearAll[i, j]
Do[Sow[5 + i], {i, 1, 10}];
For[j = 1, j < 10, j++, Sow[5 + j]];
i
j
(*
i
10
*)

They do the same thing, but For uses a global variable; Do does something like using Block.

share|improve this answer

I wouldn't use AppendTo as in VF1's answer, as it creates a copy each time you add an additional element, thus making it terribly inefficient as the list grows. As others have noted, it is almost always possible to avoid an explicit For loop by using constructs such as Map, Apply, Table or the Listable attribute for functions. In any case, I'll answer the question as stated, because it is sometimes necessary to use a For loop (or Do) if you need to do some index gymnastics or use in a compiled function.

The most straightforward way would be to use Reap and Sow (see the documentation for examples). However, these cannot be compiled. For use in a compiled function, you can use the undocumented Internal`Bag and associated functions to get the job done. As a simple example:

With[{bag = Internal`Bag[]},
    For[i = 0, i < 10, i++, Internal`StuffBag[bag, i]];
    Internal`BagPart[bag, All]
]
(* {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} *)

See this answer by Daniel Lichtblau for a brief description of bags. These are (on purpose) undocumented, and pieces from answers here and there are all we have to go on. The key points from that answer:

These functions live in the Internal` context.

  • Bag creates an expression bag, optionally with preset elements.
  • BagPart obtains parts of an expression bag, similar to Part for ordinary expressions. It can also be used on the lhs, e.g. to reset a value. StuffBag appends elements to the end of a bag.
  • We also have a BagLength, which is useful for iterating over a bag.

These functions are extrememly useful for two reasons.

  • First, this is a good way to make an extensible table in Mathematica.
  • Second, the contents of bags are evaluated but then placed in a raw expression, hence are shielded. Thus one can use these as "pointers" (in the C sense) rather than as objects, and this requires no Hold etc.
share|improve this answer
2  
Since you mention Internal`Bags along with compiling, it's important to note that these very general objects actually have rather strict limitations on their use in compiled code that are not obvious from the functional overview, requiring some experimentation to discover. @halirutan and I discussed this here. –  Oleksandr R. Nov 9 '12 at 22:39
    
@OleksandrR. Thanks, I forgot about that one. –  rm -rf Nov 9 '12 at 22:51

A For loop is generally avoidable in Mathematica for these purposes by using Table or Array, which generate a list of values automatically. There may be an extreme case, however, when you absolutely have to use a For loop (but I doubt it). In that case, do this:

Reap@For[i=0, i < 5, i++,
        Sow[someFunctionThatGeneratesNumbersOrNull[i]];
     ]//Last//First
share|improve this answer
3  
Even if you use the For loop, using AppendTo is one of the worst things possible. One can instead use Sow and Reap to collect intermediate results, or use linked lists. –  Leonid Shifrin Nov 9 '12 at 19:51
    
@LeonidShifrin what's wrong with AppendTo? –  VF1 Nov 9 '12 at 19:52
2  
@VF1: I think AppendTo creates a copy of the list with one extra item, so creating a list with length n using AppendTo is an O(n^2) operation –  nikie Nov 9 '12 at 19:54
1  
@nikie is exactly right. See also here –  Leonid Shifrin Nov 9 '12 at 19:55
    
@VF1 I can't fully understand your syntax. The For loop I have written isn't defined like a function is (i.e in the form f[x_]:= "Whatever") so what do I insert into the part of your code where you have someFunctionThatGeneratesNumersorNull[i]? –  Mel Nov 9 '12 at 19:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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