augusti
augusti

Reputation: 411

Find and remove least common element in array (Python)

I am trying to find the least common element in an array of integers and remove it, and return the list in the same order.

This is what I have done, but when the list is [1, 2, 3, 4, 5], my function should return [], but returns [2, 4] instead.

def check(data):
    for i in data:
        if data.count(i) <= 1:
            data.remove(i)
    return data


data = [1, 2, 3, 4, 5]
print check(data) 

Upvotes: 0

Views: 1678

Answers (4)

Hugh Bothwell
Hugh Bothwell

Reputation: 56634

Deleting items from a list you are iterating over causes you to skip items (ie the next item following each one you delete).

Instead, make a new list containing only the values you want to keep.

from collections import Counter

def check(data):
    ctr = Counter(data)
    least = min(ctr.values())
    return [d for d in data if ctr[d] > least]

Upvotes: 3

user123
user123

Reputation: 5407

one another try:

def check(data):
    ctr = Counter(data)
    keys = ctr.keys()
    vals = ctr.values()
    least = []
    m = min(vals)
    for i in range(0,len(vals)):
        if vals[i] == m:
            least.append(keys[i])
    print least

data = [1, 2, 3, 4, 5,1]
result = check(data)

Upvotes: 0

Dair
Dair

Reputation: 16240

You shouldn't check data.count(i) <= 1. What happens in this case: [1, 1, 2, 2, 3, 3, 3]? 1 and 2 are the least common elements but you will never delete them. Likewise it is a bad idea to mutate a list in a for loop.

One thing you can do is use the Counter class.

  1. Take an appropriate slice of the tail of the most_common() method (they entries get less frequent as you go down the list, so this is why you take the tail as opposed to the head).
  2. Then you can repeatedly search the list for these occurrences and remove them until their are no occurrences left.

Upvotes: 0

ErikR
ErikR

Reputation: 52029

You shouldn't modify (especially delete) elements from a list while you are iterating over it.

What happened is:

  1. Initially the iterator is at the 1st element, i.e. i = 1
  2. Since d.count(1) is 1, so you delete 1 from the list.
  3. The list is now [2,3,4,5], but the iterator advances to the 2nd element which is now the 3.
  4. Since d.count(3) is 1 you delete it making the list [2,4,5]
  5. The iterator advances to the 3rd element which is now 5.
  6. Again you delete the 5 making the list [2,4].

Your algorithm should:

  1. Get a count of all elements
  2. Find the smallest count.
  3. Find the elements with the smallest count.
  4. Remove the elements found in step 3 from the list.

Upvotes: 1

Related Questions