3

I'm a newbie with python and programming in general and need some help: I have a list that I've created earlier in the program by appending from a loop (i.e. I can't just redefine my list now to solve my problem), of 24 4-tuples:

elementary = [(23, 1, 18, 4), (23, 1, 6, 16), (23, 1, 4, 18), (23, 2, 18, 3), (23, 2, 12, 9), (23, 2, 9, 12), (23, 2, 3, 18), (23, 3, 18, 2), (23, 3, 2, 18), (23, 4, 18, 1), (23, 4, 1, 18), (23, 5, 14, 7), (23, 5, 7, 14), (23, 6, 16, 1), (23, 6, 9, 8), (23, 6, 8, 9), (23, 6, 1, 16), (23, 7, 14, 5), (23, 7, 5, 14), (23, 8, 9, 6), (23, 8, 6, 9), (23, 9, 12, 2), (23, 9, 8, 6), (23, 9, 6, 8), (23, 9, 2, 12), (23, 12, 9, 2), (23, 12, 2, 9), (23, 14, 7, 5), (23, 14, 5, 7), (23, 16, 1, 6), (23, 18, 4, 1), (23, 18, 3, 2), (23, 18, 2, 3), (23, 18, 1, 4)]

but now would like to get rid of the tuples that are just re-arranged... in other words, after the first tuple ((23,1,18,4)) I would let get rid of (23,1,4,18), (23,4,1,18), etc..., and if possible, I'd like to do this throughout the list, so that I only end up with 6 completely distinct 4-tuples. Is there any way to do this without going back and doing something differently earlier in my program? Any help would be greatly appreciated. Thanks!

Nathan
4,3974 gold badges22 silver badges21 bronze badges
asked Jan 24, 2013 at 3:34
1
  • 2
    Welcome to SO. What have you tried? Commented Jan 24, 2013 at 3:35

5 Answers 5

3

How about:

{tuple(sorted(t)): t for t in elementary}.values()
answered Jan 24, 2013 at 3:46
Sign up to request clarification or add additional context in comments.

Comments

2

As a 1-liner, this sorts each 4-tuple, then creates a set of the result, shich has the effect of removing the duplicates. I'm assuming your 4-tuples are allowed to have the order of elements changed.

set(tuple(sorted(i)) for i in elementary)
>>> set((5, 7, 14, 23), (6, 8, 9, 23), (2, 3, 18, 23), (1, 4, 18, 23), (1, 6, 16, 23), (2, 9, 12, 23))
answered Jan 24, 2013 at 3:38

1 Comment

This destroys the original tuples ordering, which may or may not be a problem ...
0

Do you really have only 24? If so, a slow-ish solution with some unnecessary memory allocations may work fine here, and save you programming time:

elementary_unique = set(tuple(sorted(t)) for t in elementary)

Now elementary_unique is a set rather than a list - if it matters, you can use

elementary_unique = list(set(tuple(sorted(t)) for t in elementary))

instead, but this will be a little slower than the first version.

answered Jan 24, 2013 at 3:39

1 Comment

Thank you all very much! I ended up using the elementary_unique set version but I'll give all of the suggestions a shot as a learning exercise. Thanks again!
0

You can recognize the equivalent combinations whenever sorted(tuple1) == sorted(tuple2).

The code is short and sweet:

>>> set(map(tuple, map(sorted, elementary)))
set([(5, 7, 14, 23), (6, 8, 9, 23), (2, 3, 18, 23), 
 (1, 4, 18, 23), (1, 6, 16, 23), (2, 9, 12, 23)])

If you need to preserve the ordering of each of the first distinct tuples, it takes a little more work:

>>> uniq = set()
>>> for t in elementary:
 s = tuple(sorted(t))
 if s not in uniq:
 uniq.add(s)
 print t
(23, 1, 18, 4)
(23, 1, 6, 16)
(23, 2, 18, 3)
(23, 2, 12, 9)
(23, 5, 14, 7)
(23, 6, 9, 8)
answered Jan 24, 2013 at 3:39

Comments

0

If you really want to get down and dirty with the comparisons:

In [1028]: elementary = [(23, 1, 18, 4), (23, 1, 6, 16), (23, 1, 4, 18), (23, 2, 18, 3), (23, 2, 12, 9), (23, 2, 9, 12), (23, 2, 3, 18), (23, 3, 18, 2), (23, 3, 2, 18), (23, 4, 18, 1), (23, 4, 1, 18), (23, 5, 14, 7), (23, 5, 7, 14), (23, 6, 16, 1), (23, 6, 9, 8), (23, 6, 8, 9), (23, 6, 1, 16), (23, 7, 14, 5), (23, 7, 5, 14), (23, 8, 9, 6), (23, 8, 6, 9), (23, 9, 12, 2), (23, 9, 8, 6), (23, 9, 6, 8), (23, 9, 2, 12), (23, 12, 9, 2), (23, 12, 2, 9), (23, 14, 7, 5), (23, 14, 5, 7), (23, 16, 1, 6), (23, 18, 4, 1), (23, 18, 3, 2), (23, 18, 2, 3), (23, 18, 1, 4)]
In [1029]: for e in elementary: 
 add = True 
 for a in answer: 
 if all(_e in a and e.count(_e)==a.count(_e) and len(e)==len(a) for _e in e):
 add = False
 if add:
 answer.append(e) 
In [1030]: answer
Out[1030]: 
[(23, 1, 18, 4),
 (23, 1, 6, 16),
 (23, 2, 18, 3),
 (23, 2, 12, 9),
 (23, 5, 14, 7),
 (23, 6, 9, 8)]
answered Jan 24, 2013 at 3:44

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.