0

I've got a tuple with items that can be repetitive. I need to extract only unique items.

For example:

tup = ('one', 'one', 'one', 'two', 'two','three',
'four', 'four', 'four', 'five', 'five', 'seven')

I need to get only:

'one', 'two', 'three', 'four', 'five', 'seven' (The order is not important).

How can I check the tuple and get only the values I need?

I came up with this solution but it doesn't take the last item of the tuple.

tup = ('one', 'one', 'one', 'two', 'two',
'three', 'four', 'four', 'four', 'five', 'five', 'seven')

for count, item in enumerate(tup):
    if (count+1) == len(tup):
        break
    if tup[count] != tup[count + 1]:
         print(tup[count])

Also this one but it gives the "tuple index out of range' error:

tup = ('one', 'one', 'one', 'two', 'two',
'three', 'four', 'four', 'four', 'five', 'five', 'seven')

i = 0
while len(tup):
    if tup[i] != tup[i+1]:
        print(tup[i])
    i += 1

Thank you in advance!

AntonU
  • 31
  • 5
  • Use a [`set`](https://docs.python.org/2/library/sets.html).. ? – yatu Apr 30 '19 at 15:47
  • Side-note: Your specific code (looking for *neighboring* duplicates) is basically an attempt to partially implement [`itertools.groupby`](https://docs.python.org/3/library/itertools.html#itertools.groupby). Your loop could become `for uniq, _ in itertools.groupby(tup): print(uniq)` (the `_` is indicating you're ignoring the group itself; it would just contain the value repeated however many time it appeared in that set). – ShadowRanger Apr 30 '19 at 15:54

2 Answers2

0

Since the order is not important, you can use set

tup = ('one', 'one', 'one', 'two', 'two','three',
'four', 'four', 'four', 'five', 'five', 'seven')

result = set(tup)
# {'five', 'four', 'one', 'seven', 'three', 'two'}

Another crazy solution would be to use Counter

from collections import Counter

tup = ('one', 'one', 'one', 'two', 'two','three',
'four', 'four', 'four', 'five', 'five', 'seven')

result = list(Counter(tup).keys())

Or even simpler as suggested by @ShadowRanger

list(dict.fromkeys(tup))
Sheldore
  • 37,862
  • 7
  • 57
  • 71
  • Note: If the result is to be used in a context requiring an immutable type, you can either convert the `set` back to `tuple`, or convert to `frozenset` directly (which is an immutable `set` capable of serving as a value in another `set`, or as a key in a `dict`). – ShadowRanger Apr 30 '19 at 15:50
  • No need for `Counter`; a plain `list(dict.fromkeys(tup))` would work (and on 3.6+, it would preserve order, unlike `set`s). `.keys()` isn't needed either, since `dict`s are already iterables of their keys. – ShadowRanger Apr 30 '19 at 15:51
  • @ShadowRanger: Thanks. I added your suggestion – Sheldore Apr 30 '19 at 16:01
  • All the solutions work well. The only difference is that when using set() it gives me an error that "'set' object does not support indexing". So 'list(dict.fromkeys(tuple)' works perfectly. Thanks again mates, you're awesome! – AntonU Apr 30 '19 at 16:11
0

As a matter of rule, tuples are immutable,
so not appropriate for dynamic operations like comparisons,
so you need to convert it to mutable as set which only store value once,

If you want the order to matter, you can use sorted

sslloo
  • 521
  • 2
  • 10