15

Below, list is a representative sample of my list, which contains lists of integers. I would like to be able to input:

list = {{1, 2, 3}, {3, 2, 1}, {2, 1, 3}};
f[list]

and obtain the output:

{{1, 2, 3}, {2, 1, 3}}

In other words, {3, 2, 1} is considered to be the same as {1, 2, 3}, since in reverse it is exactly {1, 2, 3}. However, {2, 1, 3} is not considered to be the same as either {1, 2, 3} or {3, 2, 1}, because it does not match these lists in forward or in reverse.

What function f can I use to accomplish this?

I tried this:

DeleteDuplicates[list, MemberQ[list, #] || MemberQ[Reverse /@ list, #] &]

but it does not work, although I'm not sure why.

ADDENDUM

Now suppose I want to input:

list = {{1, 2, 3}, {3, 2, 1}, {2, 1, 3}, {1, 2, 3}};

and obtain:

list = {{1, 2, 3}, {2, 1, 3}};

where the "second" {1, 2, 3} is removed as a "normal" duplicate. How can I do this? I could do:

DeleteDuplicates[DeleteDuplicates[list, (#1 == Reverse[#2] &)]]

but is there an easier way?

Andrew
  • 10,569
  • 5
  • 51
  • 104

3 Answers3

12

This should do the job:

DeleteDuplicates[list, SameQ[#1, #2] || SameQ[#1, Reverse@#2] &]
acl
  • 19,834
  • 3
  • 66
  • 91
  • This is what I want. For list = {{1, 2, 3}, {3, 2, 1}, {2, 1, 3}, {1, 2, 3}};, it gives {{1, 2, 3}, {2, 1, 3}}. Thanks. – Andrew May 19 '12 at 19:39
8

If your application allows for reversed elements to be interchangeable you can do this:

DeleteDuplicates[Sort[{#, Reverse@#}][[1]] & /@ list]

The advantage here is speed; this is perhaps two orders of magnitude faster on large sets than the methods already presented.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • This code works like a charm!! So fast! Not two orders faster, my test shows that it is at least three orders faster! It is necessary for large list. Thank you for your answer, Mr. Wizard! It solves my problem. – matheorem Oct 07 '15 at 08:34
  • @matheorem As always I'm glad I could help, and thanks for letting me know you found this three-year-old post useful. – Mr.Wizard Oct 07 '15 at 16:50
7

Update: in versions 10+, you can use DeleteDuplicatesBy:

list = {{1, 2, 3}, {3, 2, 1}, {2, 1, 3}, {1, 2, 3}};
DeleteDuplicatesBy[list, Union[{#, Reverse@#}]&]

{{1, 2, 3}, {2, 1, 3}}

Original answer:

You can use your condition directly

 DeleteDuplicates[list, (#1 == Reverse[#2] &)]

or use Union with SameTest

 Union[list, SameTest -> (#1 == Reverse[#2] &)]

Edit: For the new requirement, you need to Or the conditions for "sameness" (as in @acl's answer)

 DeleteDuplicates[list, (#1 == Reverse[#2] || #1 == #2 &)]
 Union[list, SameTest -> (#1 == Reverse[#2] || #1 == #2&)]
kglr
  • 394,356
  • 18
  • 477
  • 896