0

For some reason the same method is working for one function and not the other. The function that works already is defined as the following:

def is_unique1(lst):
    for item in lst:
        current_index = lst.index(item)
        if lst[current_index] in lst[current_index + 1:-1]:
            return False
    return True

You pass in a list and checks the uniqueness of it, if it is unique then return TRUE if not return FALSE. However I am then asked to create another function, except this time copy the list and sort it. Then iterate over every index for values in the list to check whether the value at that index is equal to the value at the next higher index. But it keeps returning TRUE no matter what input. The function looks like this:

def is_unique2 ( myList ):
    list_copy = list(myList)
    list_copy.sort()
    print(list_copy)
    for item in list_copy:
        index = list_copy.index(item)
        if list_copy[index] in list_copy[index + 1: -1]:
            return False
    return True

Why is this happening. Am I using the slice incorrectly. I am checking if the current value at list_copy[index] is in the index + 1. I am testing it like so:

print('\nTesting is_unique2')
print (is_unique2(['raisin', 'apricot', 'celery', 'carrot']) )
print (is_unique2(['raisin', 'apricot', 'raisin', 'carrot']) )
user4422713
  • 53
  • 1
  • 5
  • possible duplicate of [How do you remove duplicates from a list in Python whilst preserving order?](http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order) – ha9u63a7 Jan 08 '15 at 03:37
  • Is it okay to simply use `reversed()` to get the reversed list rather than using -1 [in unique1? Also, can you not call unique1 from unique2 so that you get the unique list first i.e. the working version, and then do your sorting? Try sorted() method. To make it a better question, please suply your test inputs. – ha9u63a7 Jan 08 '15 at 03:40
  • 1
    You should look up the `enumerate()` function, it will make your life a lot easier. – dursk Jan 08 '15 at 03:43

2 Answers2

3

Your bug is that by checking if list_copy[index] in list_copy[index + 1: -1] you're not checking the very last item in the list.

Remember, in Python, it's always "upper bound excluded": so somelist[a:b] will span somelist[a] included to somelist[b] excluded... for any a and b.

Easy fix: use in list_copy[index + 1:]. IOW, give no upper bound for the slice, so the slice will run all the way to the end of the list.

Incidentally, your approach is very dubious if the list's items are hashable -- in which case,

def is_unique3(myList):
    return len(myList) == len(set(myList))

will be much faster and much less bug-prone too:-)

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
-1

Try this line instead of your -1 indexed list for unique1:

lst[current_index] in lst[current_index + 1:None:-1]:
ha9u63a7
  • 6,233
  • 16
  • 73
  • 108
  • `in somelist` and `in reversed(somelist)` will **always** return exactly the same boolean value, so there's something fishy in this use of `reversed`, it seems to me. – Alex Martelli Jan 08 '15 at 03:45