15
$\begingroup$

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?

$\endgroup$

3 Answers 3

12
$\begingroup$

This should do the job:

DeleteDuplicates[list, SameQ[#1, #2] || SameQ[#1, Reverse@#2] &]
$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – Andrew
    May 19, 2012 at 19:39
8
$\begingroup$

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.

$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$
    – matheorem
    Oct 7, 2015 at 8:34
  • $\begingroup$ @matheorem As always I'm glad I could help, and thanks for letting me know you found this three-year-old post useful. $\endgroup$
    – Mr.Wizard
    Oct 7, 2015 at 16:50
7
$\begingroup$

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&)]
$\endgroup$
4
  • $\begingroup$ Okay, I think they both work now. Thanks. $\endgroup$
    – Andrew
    May 19, 2012 at 19:30
  • 1
    $\begingroup$ But now if list = {{1, 2, 3}, {3, 2, 1}, {2, 1, 3}, {1, 2, 3}} we get the duplicate element twice! $\endgroup$
    – acl
    May 19, 2012 at 19:32
  • $\begingroup$ @acl: Right, this is not what I wanted to happen, but I failed to specify this requirement in my original post. Please see my edit above. $\endgroup$
    – Andrew
    May 19, 2012 at 19:37
  • 1
    $\begingroup$ @Andrew I think my answer does do this in a simple way $\endgroup$
    – acl
    May 19, 2012 at 19:38

Your Answer

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

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