Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting rid of those deprecated Do[] loops?

12 views
Skip to first unread message

AES

unread,
Oct 12, 2008, 4:36:03 AM10/12/08
to
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];

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.)

michael.p...@googlemail.com

unread,
Oct 13, 2008, 6:15:25 AM10/13/08
to
Hi

Flatten[Table[{aa, bb, xx, yy}, {aa, 1, 2}, {bb, 10, 30, 10}],
1] // TableForm

How's that?
Cheers,
Mike

On 12 Oct, 09:36, AES <sieg...@stanford.edu> wrote:
> 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];
>
> 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},=

Jean-Marc Gulliet

unread,
Oct 13, 2008, 6:16:31 AM10/13/08
to
AES wrote:

(* Compare the order of the iterators in *)

Flatten[
Table[{aa, bb, xx, yy}, {aa, 1, 2}, {bb, 10, 30, 10}], 1]

{{1, 10, xx, yy}, {1, 20, xx, yy}, {1, 30, xx, yy}, {2, 10,
xx, yy}, {2, 20, xx, yy}, {2, 30, xx, yy}}

(* versus *)

data = {};
Do[Do[data = AppendTo[data, {aa, bb, xx, yy}], {bb, 10, 30, 10}], {aa,
1, 2}]

data

{{1, 10, xx, yy}, {1, 20, xx, yy}, {1, 30, xx, yy}, {2, 10,
xx, yy}, {2, 20, xx, yy}, {2, 30, xx, yy}}

Regards,
-- Jean-Marc

sjoerd.c...@gmail.com

unread,
Oct 13, 2008, 6:17:28 AM10/13/08
to
Multidimensional iteration is the sixth of the possible formats
described in the documentation of the Table and Do functions. The
construction that surprised you is the fifth one. Actually, you are
able to iterate over an arbitrary list of objects.

Cheers -- Sjoerd

On Oct 12, 10:36 am, AES <sieg...@stanford.edu> wrote:
> 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];
>
> 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},=

David Park

unread,
Oct 13, 2008, 6:21:13 AM10/13/08
to
data = Flatten[Table[{aa, bb, xx, yy}, {aa, 1, 2}, {bb, 10, 30, 10}],
1];
Print[data // TableForm];

And for more iterators, say filling in xx and yy also:

data =
Flatten[
Table[{aa, bb, xx, yy}, {aa, 1, 2}, {bb, {a, b}}, {xx, {1, 2}}, {yy, {c,
d}}], 3];
data // TableForm

--
David Park
djm...@comcast.net
http://home.comcast.net/~djmpark/


"AES" <sie...@stanford.edu> wrote in message
news:gcsctj$8mj$1...@smc.vnet.net...

mark mcclure

unread,
Oct 13, 2008, 6:24:40 AM10/13/08
to
On Oct 12, 4:36 am, AES <sieg...@stanford.edu> wrote:
> 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}];
> without using those universally deprecated (and even worse, nested)
> Do[ ] loops, not to mention the equally deprecated AppendTo[].

I think that Do has actually received a bit of a bum wrap in
the discussion on procedural programming in Mathematica.
The syntax of Do is, after all, identical to that of Table
(as well as to that of Plot, Integrate, Manipulate, and
others). Not surprisingly, a command like
Do[Prime[n],{n,100000}]
runs a bit faster than the corresponding Table command.

The egregious part of the code is clearly the AppendTo
statement. AppendTo is inefficient since lists are stored
as arrays that need to be recopied with each call. This is
particularly problematic with long lists. It's fairly easy
to adapt your Do loop using Reap and Sow, however.

Reap[Do[Sow[{aa, bb, xx, yy}],
{aa, 1, 2}, {bb, 10, 30, 10}]][[2, 1]]

If you're interested in efficiency, check out the following
timings:

data = {};
First[Timing[Do[Do[data =
AppendTo[data, {aa, bb, xx, yy}], {bb, 100}], {aa, 100}]]]
6.09818
----
First[Timing[Reap[Do[Sow[{aa, bb, xx, yy}],
{bb, 100}, {aa, 100}]][[2, 1]];]]
0.01853

Mark McClure

Raffy

unread,
Oct 13, 2008, 6:25:01 AM10/13/08
to
On Oct 12, 1:36 am, AES <sieg...@stanford.edu> wrote:
> 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];
>
> 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.)

Join @@ Table[{aa, bb, xx, yy}, {bb, {10, 20, 30}}, {aa, {1, 2}}] //
TableForm


Torsten Schoenfeld

unread,
Oct 13, 2008, 7:05:35 AM10/13/08
to
AES wrote:

> 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.

You can use Table[] with more than one iterator. This yields a nested
list of lists which can be flattened with Flatten[] to give the desired
result:

Table[{aa, bb, xx, yy}, {aa, 1, 2}, {bb, 10, 30, 10}]
// Flatten[#, 1] & // TableForm

-Torsten

Albert Retey

unread,
Oct 13, 2008, 7:06:25 AM10/13/08
to
AES wrote:
> 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];

> without using those universally deprecated (and even worse, nested)
> Do[ ] loops, not to mention the equally deprecated AppendTo[].

I think this is the easiest way to do what you want:

Flatten[Table[{aa, bb, xx, yy}, {aa, 1, 2}, {bb, 10, 30, 10}], 1]


> 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.
>

> 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.)

most functions that use iterators work with lists as the second part of
iterators since version 6 and that is documented for each of these
functions, at least for Table I have checked that. When used like that,
they will just iterate over the elemnts of that list, which can be lists
as in your case but also any other mathematica expression you want, eg:

Table[Integrate[expr, x], {expr, {x, x^2, x^3, Sin[x], Exp[-x]}}]


hth,

albert


AES

unread,
Oct 14, 2008, 4:58:26 AM10/14/08
to
In article <gcv77o$dse$1...@smc.vnet.net>,
"sjoerd.c...@gmail.com" <sjoerd.c...@gmail.com> wrote:

> Multidimensional iteration is the sixth of the possible formats
> described in the documentation of the Table and Do functions. The
> construction that surprised you is the fifth one. Actually, you are
> able to iterate over an arbitrary list of objects.
>
> Cheers -- Sjoerd

It's not obvious to me from either of those that the iterator "i" itself
can be a multi-dimensional variable -- though it seems to be the case.

For example, could I write an iterator of the form

{ {i,j} , { {i1,j1}, {i2,j2}, . . .}}

or something similar, and then use i and j in the Table entries, instead
writing this in the form

{ k , { {i1,j1}, {i2,j2}, . . .}}

and then using k[[1], k[[2]] in the Table entires?

And the sixth format does not produce the output that I wanted without
using Flatten -- which is an OK function, except you have to learn and
understand it well enough to know whether you do or do not need the "1"
in the second argument to get what you want.

Szabolcs Horvat

unread,
Oct 14, 2008, 5:03:54 AM10/14/08
to
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 ....

peter

unread,
Oct 15, 2008, 5:41:18 AM10/15/08
to
gimme a Do-loop any day guys; I guess I'm too old to change.
Peter

2008/10/14 AES <sie...@stanford.edu>

> In article <gcv77o$dse$1...@smc.vnet.net>,
> "sjoerd.c...@gmail.com" <sjoerd.c...@gmail.com> wrote:
>

> > Multidimensional iteration is the sixth of the possible formats
> > described in the documentation of the Table and Do functions. The
> > construction that surprised you is the fifth one. Actually, you are
> > able to iterate over an arbitrary list of objects.
> >
> > Cheers -- Sjoerd
>

0 new messages