【问题标题】:Delete similar objects in list python删除列表python中的相似对象
【发布时间】:2014-11-29 17:10:57
【问题描述】:

我在list 中有一堆Album 对象(下面发布的对象代码)。准确地说是5570。但是,在查看唯一对象时,我应该有 385。由于创建对象的方式(我不知道是否可以正确解释),我认为最好将所有对象添加到列表中,然后删除相似的。

某些对象的每个参数都有相同的字符串(artisttitletracks),我想摆脱它们。但是,我知道我不能简单地删除重复项,因为它们存储在不同的内存位置,因此并不完全相同。

谁能帮我删除重复项?

你可能会说,我对 python 还是很陌生。

提前致谢!

class Album(object) :
    def __init__(self, artist, title, tracks = None) :
        tracks = []
        self.artist = artist
        self.title = title
        self.tracks = tracks

    def add_track(self, track) :
        self.track = track
        (self.tracks).append(track)
        print "The track %s was added." % (track)

    def __str__(self) :
        return "Artist: %s, Album: %s [" % (self.artist, self.title) + str(len(self.tracks)) + " Tracks]"

【问题讨论】:

    标签: python list object duplicates


    【解决方案1】:

    虽然other answer 解决了删除重复项的根本问题,但它不允许您保留您的Album 类,这在将来会证明是有用的(甚至现在,通过它的__str__ 方法) )。因此,我认为您应该考虑实现the __eq__ method 来比较Album 类的对象。一种实现方式,along with the __ne__ method,是:

    def __eq__(self, other):
        # assuming tracks were added in the same order
        return type(other) is self.__class__ and other.artist == self.artist and other.title == self.title and other.tracks == self.tracks
    
    def __ne__(self, other):
        return not self.__eq__(other)
    

    请注意,显式检查类型而不是测试一个对象是否是另一个类的实例可以将您从具有继承的dangerous pitfall 中解救出来,而order of equality evaluation 会很重要而它不应该(例如a == bb == a 返回不同的值)。

    另一种通用解决方案,适用于简单的容器类,例如您拥有的can be found here

    def __eq__(self, other):
        return type(other) is self.__class and other.__dict__ == self.__dict__
    

    如果您也实现了the __hash__ method,您只需将您的对象添加到set 中即可保证没有重复。这里是a suggested generic implementation,用于像您这样的简单容器类:

    def __hash__(self):
        """Override the default hash behavior (that returns the id or the object)"""
        return hash(tuple(sorted(self.__dict__.items())))
    

    您还可以查看this 以获取建议的实施。


    关于您的代码的一些补充说明:

    1. 如果你用一个空列表覆盖它,那么在你的 __init__ 方法中接受 tracks 的参数是没有意义的。

    2. add_track 方法中设置self.track 毫无意义,因为它不会在任何地方使用,并且会在add_track 的下一次调用中被覆盖。 self.tracks 周围也不需要括号。您的方法应如下所示:

      def add_track(self, track) :
          self.tracks.append(track)
          print "The track %s was added." % (track)
      
    3. 您的字符串表示方法需要稍作修改。

      def __str__(self) :
          return "Artist: %s, Album: %s [%d tracks]" % (self.artist, self.title, len(self.tracks))
      

    【讨论】:

      【解决方案2】:

      您可以在元组(artist, title, tracks) 上创建您的类hashable 并将对象存储在set 中,这将只保留唯一的对象。

      【讨论】:

        猜你喜欢
        • 2021-03-15
        • 1970-01-01
        • 2020-12-05
        • 1970-01-01
        • 2012-04-03
        • 2014-06-29
        • 2016-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多