Karan Thakkar
Karan Thakkar

Reputation: 1027

How to find unique elements in a list in python? (Without using set)

Write a function that accepts an input list and returns a new list which contains only the unique elements (Elements should only appear one time in the list and the order of the elements must be preserved as the original list. ).

def unique_elements (list):
    new_list = []
    length = len(list)
    i = 0
    while (length != 0):
        if (list[i] != list [i + 1]):
            new_list.append(list[i])
        i = i + 1
        length = length - 1
    '''new_list = set(list)'''
    return (new_list)

#Main program
n = int(input("Enter length of the list: "))
list = []
for i in range (0, n):
    item = int(input("Enter only integer values: "))
    list.append(item)
print ("This is your list: ", list)
result = unique_elements (list)
print (result)

I am stuck with this error:

IndexError: list index out of range

Upvotes: 6

Views: 27726

Answers (10)

Nandita Puri
Nandita Puri

Reputation: 1

So if you are at the last element, then if (list[i] != list [i + 1]): will try to take a value out of the list which is not present there and that is why the error is showing that the list is out of range.

Upvotes: 0

Subham
Subham

Reputation: 411

Use of collections is best IMO, Accepted answer is simplest, Adding another approach using dict where you can check frequency as well,


text = [100, 3232, 3232, 3232, 57, 57, 90]
# create empty dictionary
freq_dict = {}
 
# loop through text and count words
for word in text:
    # set the default value to 0
    freq_dict.setdefault(word, 0)
    # increment the value by 1
    freq_dict[word] += 1
 
unique_list = [key for key,value in freq_dict.items()]

print(unique_list )

print(freq_dict )
[100, 3232, 57, 90]
{100: 1, 3232: 3, 57: 2, 90: 1}

[Program finished] 

You can also print by values based on requirements.

Upvotes: 0

Kailas
Kailas

Reputation: 1

Found an easier approach for people on Python 3.7.

Using a dictionary:

list(dict.fromkeys(mylist))

Upvotes: -2

Nelson M
Nelson M

Reputation: 1728

You can work this out using sets and set comprehension syntax is in most cases overlooked. Just as lists sets can also be generated using comprehension.

elements = [1, 2, 3, 3, 5, 7, 8, 7, 9]
unique_elements = {element for element in elements}
print(unique_elements)

Upvotes: -2

user8074681
user8074681

Reputation:

l = [1, 2, 2, 3,4,5,6,5,7,8]
myList = []
[ myList.append(item) for item in l if item not in myList]
print(myList)

Upvotes: 2

Fuji Komalan
Fuji Komalan

Reputation: 2047

The problematic line is > if (list[i] != list [i + 1]): < (6th line in your code).

Reason: Imagine your list has got 4 elements.

Eg: mylist = [ 1, 2,2,3].

mylist[i] != mylist [i + 1]

In the last iteration 'i' will be 4 , so i + 1 will be 5.

There is no such 5th index in that list, because list indexes are counted from zero.

mylist[0] = 1

mylist[1] = 2

mylist[2] = 2

mylist[3] = 3

mylist[4] = No Index

mylist[5] = No Index

    def unique_elements (list):
        new_list = []

   # Replace the while with a for loop** 

        for i in list:
          if i not in new_list:
            new_list.append(i)


        return (new_list)

    #Main program
    n = int(input("Enter length of the list: "))
    list = []
    for i in range (0, n):
        item = int(input("Enter only integer values: "))
        list.append(item)
    print ("This is your list: ", list)
    result = unique_elements (list)
    print (result)

Upvotes: 1

timgeb
timgeb

Reputation: 78780

O(n) solution without using a set:

>>> from collections import Counter, OrderedDict
>>> class OrderedCounter(Counter, OrderedDict):
...     pass
... 
>>> lst = [1, 2, 2, 3, 4, 5, 4]
>>> [x for x,c in OrderedCounter(lst).items() if c==1]
[1, 3, 5]

Upvotes: 2

George Petrov
George Petrov

Reputation: 2849

One line implementation:

list = [100, 3232, 3232, 3232, 57, 57, 90]
new_list = []

[new_list.append(x) for x in list if x not in new_list]

print(new_list)

Prints:

[100, 3232, 57, 90]

Upvotes: 1

6502
6502

Reputation: 114579

The problem with your code is that you are looping length times but checking list[i] with list[i+1], thus accessing an element past the end of the input list (e.g. in a list with 6 elements there are 6-1=5 pairs of consecutive elements).

A second issue with your code is that an input with only one element [1] should give as output [1] even if this element is not different from any other. The input text means you should remove elements that are equal to other elements already present, not that you should keep elements that are different from the next one.

Another issue is that you're only checking for consecutive duplicates i.e. given the input list [1, 2, 1, 2] your logic wouldn't detect any duplication... looks like the exercise instead requires in this case as output of [1, 2].

A trace for a simple algorithm to do this is

for each element in input
   if the element has not been included in output
       add the element to the end of output

Note also that to check if an element is present in a list Python provides the in operator (e.g. if x in output: ...) that can save you an explicit loop for that part.

As a side note naming an input parameter list is considered bad practice in Python because list is the name of a predefined function and your parameter is hiding it.

Upvotes: 3

Joe T. Boka
Joe T. Boka

Reputation: 6581

This is the simplest way to do it:

a = [1, 2, 2, 3]
b = []
for i in a:
    if i not in b:
        b.append(i)
print (b)
[1, 2, 3]

Upvotes: 18

Related Questions