How to remove duplicate item in List?

2019-08-27 02:24发布

If I have a list for example :

courses = [{name: a, course: math, count:1}]

and if I input again name: a course: math the list will be

  courses = {name: a, course: math, count:2}

I just want the item with the same name and course will not append to the list but only increasing 'count' key item.

I tried :

def add_class(inputname,inputcourse):
for i in (len(courses)):
      if courses[i]['name']== inputname and courses[i]['course']==inputcourse:
          courses[i][count]+=1
      else :
          newdata = {"name":inputname, "course":inputcourse,count:1}
          #i put count because this item is the first time.
          courses.append(newdata)
      print courses

I expect the output is class = {name: a, course: math, count:2} but the actual output is class = [{name: a, course: math, count:2},{name: a, course: math, count:1}] if i input a new data like name : a, course: physic the output will be [{name:a,course:physic,count:1},{name: a, course: math, count:2},{name: a, course: math, count:1}]

标签: python
2条回答
再贱就再见
2楼-- · 2019-08-27 02:51

May I suggest you a different approach?

Instead of using a list of dictionaries wich may be complicated to manage in your case, write your own class to store "name" and "course".

class NC:
    def __init__(self, n, c):
        self.name = n
        self.course = c

    def __hash__(self):
        return hash((self.name, self.course))

    def __eq__(self, other):
        if self.__hash__() == other.__hash__():
            return True
        else:
            return False

    def __repr__(self):
        return "[{}: {}]".format(self.name, self.course)

By defining the special method __hash__ and __eq__ you make your objects hashable, so they can be counted by Counter. If you write something like this:

from collections import Counter

a = NC("a", "math")
b = NC("b", "physics")
c = NC("a", "math")

l = [a, b, c]

lc = Counter(l)
print lc

the print will gives you Counter({[a: math]: 2, [b: physics]: 1})

With this approach, you may just append all the NC objects to your list and at the end use Counter to get the repetitions.

EDIT after request in the comment.

To do the same thing in "real time" you can create an empty counter an then update it.

from collections import Counter

lc = Counter()

lc.update([NC("a", "math")])
print lc #this prints: Counter({[a: math]: 1})

lc.update([NC("b", "physics")])
print lc #this prints: Counter({[a: math]: 1, [b: physics]: 1})

lc.update([NC("a", "math")])
print lc #this prints: Counter({[a: math]: 2, [b: physics]: 1})

Just remember that Counter.update wants an iterable, so if you want to add one element to the Counter, you have to give in input a list with that one element. Of course you may also add more elements togheter, for example: lc.update([NC("b", "physics"), NC("c", "chemistry")]) is valid and both objects are added to the counter.

查看更多
仙女界的扛把子
3楼-- · 2019-08-27 02:56

You can use a for else clause. The else part will be called only if break is not reached, here is an example for you

courses = []
courses.append({'name': 'a', 'course': 'math', 'count': 1})
def add_course(d):
    for course in courses:
        if course['course'] == d['course'] and course['name'] == d['name']:
            course['count'] += 1
            break
    else:
        d['count'] = 1
        courses.append(d)


add_course({'name': 'a', 'course': 'math'})
add_course({'name': 'a', 'course': 'english'})
print(courses)

As an output you have [{'name': 'a', 'course': 'math', 'count': 2}, {'name': 'a', 'course': 'english', 'count': 1}]

查看更多
登录 后发表回答