按id删除Python列表中的重复项

2024-05-15 01:35:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我在解析一棵树的时候建立了一个高层对象的大列表。但是,在这一步之后,我必须从列表中删除重复项,我发现在python2中这个新步骤非常慢(这是可以接受的,但是在python3中仍然有点慢)。但是我知道不同的物体实际上有不同的id。为此,我通过以下步骤设法获得了一个速度更快的代码:

  • 解析时将所有对象追加到一个列表中
  • 使用key=id选项对列表排序
  • 迭代排序后的列表,如果前一个元素具有相同的id,则删除该元素

因此,我有了一个可以正常运行的代码,但是我想知道是否可以在Python中更直接地实现这个任务。在

示例。让我们构建两个相同的对象,它们具有相同的值,但具有不同的id(例如,为了依赖标准库,我将使用一个fractions.Fraction):

from fractions import Fraction
a = Fraction(1,3)
b = Fraction(1,3)

现在,如果我试图通过使用pythonic list(set(...))来实现我想要的结果,我得到的结果是错误的,因为{}只保留了两个值中的一个(它们是相同的,但是具有不同的id)。在

我现在的问题是:用id而不是用value删除重复项,最具python、最可靠、最快捷的方法是什么?列表的顺序并不重要,是否需要更改。


Tags: 对象代码id元素列表排序步骤速度
2条回答

请小心,因为使用id进行区分可能会失败,因为python可能会优化存储的一些基本类型:

a = "foo"
b = "foo"
print(a is b)

收益率

^{pr2}$

无论如何,如果您想处理标准对象(即使是非散列对象),您可以将它们存储在字典中,并将它们id作为键。在

分数示例:

from fractions import Fraction
a = Fraction(1,3)
b = Fraction(1,3)

d = dict()

d[id(a)] = a
d[id(b)] = b

print(d.values())

结果:

dict_values([Fraction(1, 3), Fraction(1, 3)])

您应该重写^{}方法,使其依赖于对象id,而不是其值。但是请注意,您的对象也必须是散列的,所以您也应该定义一个适当的^{}方法。在

class My_obj:
    def __init__(self, val):
        self.val = val

    def __hash__(self):
        return hash(self.val)

    def __eq__(self, arg):
        return id(self) == id(arg)

    def __repr__(self):
        return str(self.val)

演示:

^{pr2}$

相关问题 更多 >

    热门问题