4
$\begingroup$

I have a list of lists

proof = List[{-1, 2, 3, -1}, {-1, 2, 4, -1}, {-1, 7, 9, -1}, {-1, 7, 2, -1}, 
  {-1, 3, 9, -1}, {-1, 7, 9, -1}, {-1, 5, 9, -1}];

I would like to obtain the same list discarding the first and last entry of each sublist (those marked with -1.

Rest[Most[proof[[1]]]]

works for one of the lists, but when I tried

Rest[Most[proof[[All]]]]

it doesn't work and the output is the same as

Rest[Most[proof]]

(it discards the two external sublists).

I could use

proof = Rest[Reap[Do[Sow[Rest[Most[proof[[k]] ]]], {k,1,7}]]]

Rest is used to discard a NULL result and this returns a triple nested list. Is there an easier/elegant way of doing this?

$\endgroup$
3
  • 2
    $\begingroup$ Rest[Most[#]& /@ proof or equivalently Map[Rest[Most[#]&,proof] $\endgroup$
    – andre314
    Jul 8, 2017 at 13:47
  • 2
    $\begingroup$ There is also Drop[proof, None, {1, -1, 3}] $\endgroup$
    – Coolwater
    Jul 8, 2017 at 14:19
  • $\begingroup$ proof.SparseArray[Band[{2, 1}] -> 1, {4, 2}]. See here $\endgroup$
    – user1066
    Jul 10, 2017 at 21:23

3 Answers 3

12
$\begingroup$
proof[[All, 2;;-2]] (* Shortest and most likely to be the fastest *)
Rest /@ Most /@ proof
Rest @* Most /@ proof (* thanks: Bob Hanlon *)
Composition[Rest, Most] /@ proof
ArrayPad[proof, {{0}, -1}]
Cases[proof, {_, x___, _} :> {x}]
Replace[proof, {_, a___, _} :> {a}, 1] (* thanks: eldo *)
ReplacePart[proof, {{_, 1}, {_,-1}}:> Nothing]
Extract[proof, {All, 2 ;; -2}] (* version 10+ only *)
MapAt[Nothing, proof, {{All, {1,-1}}}] (* version 10+ only *)
Drop[RotateLeft /@ proof, None, -2]

all give

{{2, 3}, {2, 4}, {7, 9}, {7, 2}, {3, 9}, {7, 9}, {5, 9}}

And, for fun, so does

#[[2 ;; -2]] & @ proof 

enter image description here

$\endgroup$
10
  • $\begingroup$ The last can be written more compactly as Rest@*Most /@ proof $\endgroup$
    – Bob Hanlon
    Jul 8, 2017 at 14:10
  • $\begingroup$ Thank you @Bob. Still in version 9 here. I will add your suggestion. $\endgroup$
    – kglr
    Jul 8, 2017 at 14:22
  • $\begingroup$ For completeness: Replace[proof, {_, a___, _} :> {a}, 2] $\endgroup$
    – eldo
    Jul 9, 2017 at 10:29
  • 2
    $\begingroup$ While it is fun to find as many ways as possible to do a certain thing, it might also be helpful to the OP to note which method should be considered the optimal for large data. For OP's problem, it doesn't really matter, of course, but I would like to chip in that proof[[All, 2 ;; -2]] should be considered preferable for general arrays of data. $\endgroup$ Jul 9, 2017 at 15:39
  • 2
    $\begingroup$ @eldo Don't you mean Replace[. . ., 1]? $\endgroup$
    – Mr.Wizard
    Jul 10, 2017 at 0:27
2
$\begingroup$

For your special list (- + + ... + -)

Pick[#, Sign @ #, 1]& @ proof

{{2, 3}, {2, 4}, {7, 9}, {7, 2}, {3, 9}, {7, 9}, {5, 9}}

$\endgroup$
1
  • 1
    $\begingroup$ As the OP,I would like to obtain the same list discarding the first and last entry of each sublist. It is not a good solution.But anyway,it is a witty usage of Sign. $\endgroup$
    – yode
    Jul 9, 2017 at 5:37
1
$\begingroup$
SequenceCases[proof, {{_, x__, _}} :> {x}];
(* {{2, 3}, {2, 4}, {7, 9}, {7, 2}, {3, 9}, {7, 9}, {5, 9}} *)

ReplaceList[proof, {___, {_, a__, _}, ___} :> {a}] (* one of the many ways *)
(* {{2, 3}, {2, 4}, {7, 9}, {7, 2}, {3, 9}, {7, 9}, {5, 9}} *)

proof /. {_, x__Integer, _} :> {x}
(* {{2, 3}, {2, 4}, {7, 9}, {7, 2}, {3, 9}, {7, 9}, {5, 9}} *)

(* since only first and last entries are -1, you can do*)
DeleteCases[proof, -1, 2]
or 
DeleteCases[proof, Except[Integer, -1], 2]
(* {{2, 3}, {2, 4}, {7, 9}, {7, 2}, {3, 9}, {7, 9}, {5, 9}} *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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