Re: Getting rid of those deprecated Do[] loops?
- To: mathgroup at smc.vnet.net
- Subject: [mg92807] Re: Getting rid of those deprecated Do[] loops?
- From: Szabolcs Horvat <szhorvat at gmail.com>
- Date: Tue, 14 Oct 2008 04:54:44 -0400 (EDT)
- Organization: University of Bergen
- References: <gcsctj$8mj$1@smc.vnet.net>
AES wrote: >>> Getting rid of those deprecated Do[] loops? Why are you making everything black and white? Do[] is certainly not deprecated. In fact it is often the best solution. This is of course just about the esthetics of the code, but when some time ago I wrote a message about why I'd like to see For[] banished from Mathematica, one of the reasons I mentioned that it can be usually converted to a more compact (and in my subjective opinion, more readable) Do[] loop. > Trying to think of a "two-variable iterator" approach that will let one > produce the same results as > > data = { }; > Do[ > Do[ > data = AppendTo[data, {aa, bb, xx, yy}], > {bb, 10, 30, 10}], > {aa, 1, 2}]; > Print[data // TableForm]; 1. One of the reasons why I consider Do[] more appropriate for basic iteration than For[] is that it supports multiple iterators. First change: data = {}; Do[data = AppendTo[data, {aa, bb, xx, yy}], {bb, 10, 30, 10}, {aa, 1,2}]; Print[data // TableForm]; 2. I believe that you are aware that ; does nothing after Do[] or Print[]. You probably also know that Print[] is unnecessary here. Second change: data = {}; Do[data = AppendTo[data, {aa, bb, xx, yy}], {bb, 10, 30, 10}, {aa, 1, 2}] data // TableForm 3. Do look up the difference between Append and AppendTo ... Third change: Use either data = {}; Do[data = Append[data, {aa, bb, xx, yy}], {bb, 10, 30, 10}, {aa, 1, 2}] data // TableForm or data = {}; Do[AppendTo[data, {aa, bb, xx, yy}], {bb, 10, 30, 10}, {aa, 1, 2}] data // TableForm 4. Mathematica's List is a contiguous array in memory. Therefore the time to construct a list this way grows quadratically with the list's length. Variations on curing this problem: a. Avoid appending by generating results in one step: data = Join @@ Table[{aa, bb, xx, yy}, {aa, 1, 2}, {bb, 10, 30, 10}]; data // TableForm b. Use Sow/Reap, which were specifically designed for colleting sequentially generated data: data = First@Last@Reap[ Do[Sow[{aa, bb, xx, yy}], {bb, 10, 30, 10}, {aa, 1, 2}] ]; data // TableForm c. Use a "linked list" to accumulate results: data = {}; Do[data = {data, temp[aa, bb, xx, yy]}, {bb, 10, 30, 10}, {aa, 1, 2}] Flatten[data] /. temp -> List // TableForm I think that point a. is the best solution for this specific problem, but using this information you should be able to judge by yourself, and construct appropriate solutions for similar but different problems ... > > without using those universally deprecated (and even worse, nested) > Do[ ] loops, not to mention the equally deprecated AppendTo[]. > > Somewhat to my surprise, the construction > > Table[{aa = kk[[1]]; bb = kk[[2]]; aa, bb, xx, yy}, > {kk, {{1, 10}, {1, 20}, {1, 30}, {2, 10}, {2, 20}, > {2,30}}} > ] // TableForm > > using a two-dimensional iterator iterator variable kk, actually does > this, though the "iterator list" is obviously a bit messy. > > Simpler way of defining an iterator to do this? In more than two > iterator dimensions (aa, bb, cc,...)? (with no functional dependence > between the values of aa, bb, cc). > > Is the concept of a multi-dimensional iterator variable kk mentioned in > the M6 documentation anywhere? (A search on "Iterate" or "iteration" > brings up 193 hits at 10 per screen.) Have you at all looked at the documentation of Table ... ? It's the 6th item ... The only missing piece was Join, which I am sure you must have encountered before ....