4
$\begingroup$

Consider a big list where all the inner lists' lengths are the same

 list = {{x1, y1, z1, t1}, {x2, y2, z2, t2}, {x3, y3, z3, t3}, ...};
 elementNo = {4, 3, 2};

I want output like this,

{{x1}, {x2}, {x3}, ...}

That is, when I specify elementNo as {4, 3, 2}, I mean the elements at positions 2, 3 and 4 in the sub-lists should be removed -- I want the elements at position 1 only. When I specify elementNo as {2, 3}, I want

 {{x1, t1}, {x2, t2}, {x3, t3}, ...}

How can I do this?

$\endgroup$
  • $\begingroup$ Hm... okay, I guess I see now. You should describe this problem as deleting elements, as that is what it is. $\endgroup$ – Mr.Wizard Mar 18 '13 at 6:07
  • $\begingroup$ @Mr.Wizard I tried for getting that output,but I didn't get it. $\endgroup$ – subbu Mar 18 '13 at 6:10
  • $\begingroup$ @Mr.Wizard we have to remove the specific position elements from the main list,that specific element position getting from elementNO. $\endgroup$ – subbu Mar 18 '13 at 6:12
  • $\begingroup$ I answered this. Please take the time to Accept some of the answers to your earlier questions. $\endgroup$ – Mr.Wizard Mar 18 '13 at 6:15
  • $\begingroup$ @m_goldberg You're obsessive about your edits, aren't you? $\endgroup$ – Mr.Wizard Mar 18 '13 at 6:52
9
$\begingroup$

Another option:

f[list_, pos_] := Module[{x = list},
  x[[All, pos]] = Sequence[];
  x]
$\endgroup$
4
$\begingroup$
f1[list_, spec_] := With[{sp = List /@ spec}, Delete[#, sp] & /@ list]

f1[list, {4, 3, 2}]
f1[list, {2, 3}]
{{x1}, {x2}, {x3}}
{{x1, t1}, {x2, t2}, {x3, t3}}
f2[list_, spec_] := list[[ All, Complement[Range@Length@First@list, spec] ]]

f2[list, {4, 3, 2}]
f2[list, {2, 3}]
{{x1}, {x2}, {x3}}
{{x1, t1}, {x2, t2}, {x3, t3}}
$\endgroup$
  • 4
    $\begingroup$ +1. Note that a more efficient form of List /@ specis Transpose[{spec}]. $\endgroup$ – Leonid Shifrin Mar 18 '13 at 8:33
  • $\begingroup$ @Leonid True, however I thought clarity might be better for this answer, and f2 is the higher performance method anyway. $\endgroup$ – Mr.Wizard Mar 18 '13 at 10:37
  • $\begingroup$ Ok, makes sense. $\endgroup$ – Leonid Shifrin Mar 18 '13 at 11:11
2
$\begingroup$

Try this one

list = RandomInteger[50, {10, 4}]
new = {};
elemNo = {4, 3, 2};
new = Map[Delete[#, {{elemNo[[1]]}, {elemNo[[2]]}, {elemNo[[3]]}}] &,list]
$\endgroup$
  • 1
    $\begingroup$ That won't work if the elemNo list is a different length. It's also not efficiently written, as you could much more easily do: Map[Delete[#, List /@ elemNo] &, list]. This is what I did in my answer for the function f1 but with the additional optimization of doing the List /@ elemNo once and inserting it using With. $\endgroup$ – Mr.Wizard Mar 18 '13 at 6:49
2
$\begingroup$

Here's another alternative:

f[list_, pos_] := With[{p = pos ~Sort~ Greater}, Fold[# ~Drop~ {#2} &, #, p] & /@ list]

f[list, {2, 3}]
(* {{x1, t1}, {x2, t2}, {x3, t3}} *)

If you can guarantee that the positions to be dropped will be input in descending order, you can drop the sorting step.

$\endgroup$
1
$\begingroup$

here is the way I would do it using my Excel mindset,

list = {{x1, y1, z1, t1}, {x2, y2, z2, t2}, {x3, y3, z3, t3}};
elementNo = {4, 3, 2};
todelete = {#} & /@ Sort@elementNo
tokeep = Delete[Range@Length@First@list, todelete]
remaining = Take[list, All, tokeep]

or something similar.

$\endgroup$
1
$\begingroup$

Another way, using Outer and Extract:

data = {{x1, y1, z1, t1}, {x2, y2, z2, t2}, {x3, y3, z3, t3}};
unwanted1 = {4, 3, 2};
unwanted2 = {2, 3};

extractComplement[data_List, spec_List] :=
  Module[{dataSize, subSize, survivors},
    dataSize = Length@data;
    subSize = Length@data[[1]];
    survivors = Outer[List, Range@dataSize, Complement[Range@subSize, spec]];
    Extract[data, #] & /@ survivors]

extractComplement[data, unwanted1]

{{x1}, {x2}, {x3}}

extractComplement[data, unwanted2]

{x1, t1}, {x2, t2}, {x3, t3}

$\endgroup$
1
$\begingroup$

If all sublists are indeed of the same length, use Transpose:

Transpose@Delete[Transpose@list, List /@ elementNo]
{{x1}, {x2}, {x3}}

Note that you can use the shorthand notation for Transpose, which makes the code really short:

Mathematica graphics

With other elementNo:

elementNo = {3, 2};
Transpose@Delete[Transpose@list, List /@ elementNo]
{{x1, t1}, {x2, t2}, {x3, t3}}
$\endgroup$
  • $\begingroup$ While you're using Transpose how about Delete[list\[Transpose], {elementNo}\[Transpose]]\[Transpose]? Looks great in the Notebook. :-) $\endgroup$ – Mr.Wizard Mar 18 '13 at 10:35
  • $\begingroup$ @Mr.Wizard I've set my PerformanceGoal to "Speed" instead of "CodeGolf". An extra Transpose might be just too much for a modern computer... :) $\endgroup$ – István Zachar Mar 18 '13 at 10:41
1
$\begingroup$
list = {{x1, y1, z1, t1}, {x2, y2, z2, t2}, {x3, y3, z3, t3}};
elementNo = {4, 3, 2};

MapAt[Nothing, list, Thread[{All, elementNo}]]

{{x1}, {x2}, {x3}}

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