Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2012

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: List Manipulation

  • To: mathgroup at smc.vnet.net
  • Subject: [mg124973] Re: List Manipulation
  • From: Ray Koopman <koopman at sfu.ca>
  • Date: Wed, 15 Feb 2012 04:42:27 -0500 (EST)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • References: <jh6k3l$jrc$1@smc.vnet.net>

On Feb 11, 12:46 pm, Murta <rodrigomur... at gmail.com> wrote:
> Hi All
>
> I'm looking some better solution for the below list manipulation:
> l1={a,b,c};
> l2={{1,2,3},{4,5,6},{7,8,9}};
> output = {{a,1},{a,2},{a,3},{b,4},{b,5},{b,6},{c,7},{c,8},{c,9}}
> It's a simple distributions of terms.
>
> I used this solution, but I think it's not an elegant one:
>
> f[a_, b_] := Flatten[{a, #}] & /@ b;
> MapThread[f, {l1, l2}] // Flatten[#, 1] &
>
> Some clue?
> Maybe with Outer or Inner?
> Thanks in advance!
> Murta

This seems as appropriate an occasion as any to sound off about
something that's been bugging me for a while. IMHO, the most elegant
(although perhaps not the most efficient) solution to the problem is

  L1 = {a,b,c};
  L2 = { {1,2,3}, {4,5,6}, {7,8,9} };
  Join @@ Thread /@ Thread @ {L1, L2}

  { {a,1},{a,2},{a,3}, {b,4},{b,5},{b,6}, {c,7},{c,8},{c,9} }

Extending the problem to include cases where the second array may be
ragged, we have

  L3 = { {1,2}, {3,4,5}, {6,7,8,9} };
  Join @@ Thread /@ Thread @ {L1, L3}

  { {a,1},{a,2}, {b,3},{b,4},{b,5}, {c,6},{c,7},{c,8},{c,9} }

The same code handles both cases.

Now consider code that uses Inner. The following works for
rectangular arrays but not for ragged:

  Join @@ Transpose @ Inner[List, L1, L2, List]

  { {a,1},{a,2},{a,3}, {b,4},{b,5},{b,6}, {c,7},{c,8},{c,9} }

  Join @@ Transpose @ Inner[List, L1, L3, List]

  { a, b, c, {1,2}, {3,4,5}, {6,7,8,9} }

I have no problem with that. Rectangular is a special case, and
there is nothing strange about code that works in a special case
but fails in more general cases.

However, the following code works for ragged arrays but fails if
the array happens to be rectangular:

  Inner[ Thread@{##}&, L1, L3, Join]

  { {a,1},{a,2}, {b,3},{b,4},{b,5}, {c,6},{c,7},{c,8},{c,9} },

  Inner[ Thread@{##}&, L1, L2, Join]

  { {a,1,b,4,c,7}, {a,2,b,5,c,8}, {a,3,b,6,c,9} }.

I don't see that as analogous to the failure of division to handle
a zero divisor, or of Dot to handle matrices that are not conformal
for multiplication. Those are cases where the function is naturally
undefined. But here there is no reason why the rectangular case
should be treated specially. Inner arbitrarily *defines* it as
special.

The basic definition of Inner, unchanged since Version 1, is

  Inner[f, {a,b,c}, {x,y,z}, g]

  g[ f[a,x], f[b,y], f[c,z] ].

The only requirement is that the second and third arguments --
e.g., {a,b,c} and {x,y,z}, in the example -- be lists with the same
lengths.

If x,y,z are themselves lists with different lengths then we have,
for instance,

  Inner[f, {a,b,c}, { {x1}, {y1,y2}, {z1,z2,z3} }, g]

  g[ f[a,{x1}], f[b,{y1,y2}], f[c,{z1,z2,z3}] ],

which is consistent with the basic definition. However, if x,y,z
happen to have the same lengths then the interpretation changes:

  Inner[f, {a,b,c}, { {x1,x2}, {y1,y2}, {z1,z2} }, g]

  { g[f[a,x1], f[b,y1], f[c,z1]], g[f[a,x2], f[b,y2], f[c,z2]] },

which is not always consistent with the basic definition. At the very
least, this should be pointed out in the Possible Issues section of
the documentation for Inner.



  • Prev by Date: Re: surprising timings for multiplication of diagonalmatrix and full matrix
  • Next by Date: Re: question about NIntegrate
  • Previous by thread: Re: List Manipulation
  • Next by thread: nsmet error in a simple equation which I can solve by hand