8
$\begingroup$

We have a list as

list = {{h, {{1, 1, 2}, {1, 3}, {1, 4}}}, {k, {{1, 3}, {2, 3, 1}, {2, 
 2, 1}, {2, 1}}}, {r, {{1, 1, 2}, {3, 4}, {2, 1}, {2, 4}, {2, 1, 
 5}}}};

We wish to have another list containing just pairs:

list = {{h, { {1, 3}, {1, 4}}}, {k, {{1, 3}, {2, 1}}}, {r, { {3, 4}, {2, 1}, {2, 4}}}};

How can we use Pick or Select or other functions for this aim?

Thank you in advance

$\endgroup$
5
$\begingroup$

Select can be used to identify pairs in sub-lists, such as

Select[list[[1, 2]], Length@# == 2 &]

(* {{1, 3}, {1, 4}} *)

Then, use Map to apply Select to every sub-list:

{First@#, Select[Last@#, Length@# == 2 &]} & /@ list

(* {{h, {{1, 3}, {1, 4}}}, {k, {{1, 3}, {2, 1}}}, {r, {{3, 4}, {2, 1}, {2, 4}}}} *)
$\endgroup$
1
  • $\begingroup$ I could understand. it is amazing solution. Without using additional IF condition which was in my decesion $\endgroup$ May 3 '17 at 5:24
14
$\begingroup$

I think you'll find the simple

DeleteCases[list, {_, _, __}, {3}]

to be a bit more efficient...

$\endgroup$
1
  • 2
    $\begingroup$ simple and efficient...+1 winner for me:) $\endgroup$
    – ubpdqn
    May 3 '17 at 6:59
7
$\begingroup$

Using Apply

f[x_, y_] := {x, y};
f[___] := Nothing;
Apply[f, list, {3}]
$\endgroup$
7
$\begingroup$

Using ReplaceAll (/.)

list /.  {_Integer, _Integer, __} :> Nothing

One needs to carefully specify the replacement rules however, try for example

list /.  {_, _, __} :> Nothing
(* Nothing *)

Rule replacement is actually quite efficient (relatively speaking) in this case, compare the above to @ciao's answer:

testList = Join[Apply[Sequence]@Table[list, 200000]]

(res1 = testList /.  {_Integer, _Integer, __} :> Nothing); // AbsoluteTiming
(* {2.55462, Null} *)
(res2 = DeleteCases[testList, {_, _, __}, {3}]); // AbsoluteTiming
(* {0.769297, Null} *)
res1 == res2
(* True *)

For a solution based on rule replacement a factor of ~3 worse than the (supposedly) fastest method isn't half bad.

$\endgroup$
2
  • 1
    $\begingroup$ One needs to carefully specify the replacement rules... well how about Replace[list, {_, _, __} :> Nothing, {3}]? $\endgroup$
    – LLlAMnYP
    May 3 '17 at 8:10
  • $\begingroup$ @LLlAMnYP that one works as well but I though it less general (but maybe safer to use) in case of more deeply nested lists $\endgroup$
    – Sascha
    May 3 '17 at 8:17
6
$\begingroup$

Pattern Matching:

xss = {{h, {{1, 1, 2}, {1, 3}, {1, 4}}}, {k, {{1, 3}, {2, 3, 1}, {2, 
 2, 1}, {2, 1}}}, {r, {{1, 1, 2}, {3, 4}, {2, 1}, {2, 4}, {2, 1, 
 5}}}}
xss //. {xs___, {_Integer, _Integer, __}, ys___} -> {xs, ys}

Test (Special Case, 200000 copies of xss):

xss = {{h, {{1, 1, 2}, {1, 3}, {1, 4}}}, {k, {{1, 3}, {2, 3, 1}, {2, 
     2, 1}, {2, 1}}}, {r, {{1, 1, 2}, {3, 4}, {2, 1}, {2, 4}, {2, 1, 
     5}}}}
testList = Join[Apply[Sequence]@Table[xss, 200000]]
f[xss_] := f[xss] = 
  xss //. {xs___, {_Integer, _Integer, __}, ys___} -> {xs, ys}
AbsoluteTiming[testList // Map[f] ]

enter image description here

$\endgroup$
10
  • 2
    $\begingroup$ Using ReplaceRepeated this way is very inefficient. $\endgroup$
    – Sascha
    May 3 '17 at 7:21
  • $\begingroup$ The execution time is 0.000057 seconds. {0.000057, {{h, {{1, 3}, {1, 4}}}, {k, {{1, 3}, {2, 1}}}, {r, {{3, 4}, {2, 1}, {2, 4}}}}} $\endgroup$ May 3 '17 at 7:29
  • $\begingroup$ try the same with a longer list e.g. a form of testlist from my answer (maybe with 1000 copies of the original list) $\endgroup$
    – Sascha
    May 3 '17 at 7:41
  • 2
    $\begingroup$ Memoization is cheating ;-). You are memoizing just three inputs, this is not a representative test. $\endgroup$
    – LLlAMnYP
    May 3 '17 at 8:01
  • 1
    $\begingroup$ @Sascha precisely. But Map[# //. {xs___, {_Integer, _Integer, __}, ys___} :> {xs, ys} &, testList, {2}] is okay-ish. $\endgroup$
    – LLlAMnYP
    May 3 '17 at 8:08
5
$\begingroup$

An example with MapAt:

MapAt[Cases[#, _?(Length@# == 2 &)] &, list, {All, 2}]

yielding:

(* {{h, {{1, 3}, {1, 4}}}, {k, {{1, 3}, {2, 1}}}, {r, {{3, 4}, {2, 
    1}, {2, 4}}}}*)
$\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.