是否有更多的Pythonic方法来阻止向列表添加副本?

时间:2013-11-07 11:31:18

标签: python list

是否有更多Pythonic(或简洁)方法来阻止向列表添加副本?

if item not in item_list:
    item_list.append(item)

或者这实际上是一种廉价的操作?

6 个答案:

答案 0 :(得分:8)

由于@ hcwsha的原始解决方案已经被替换,我在这里录制它:

seen = set(item_list)

# [...]

if item not in seen:
    seen.add(item)
    item_list.append(item)

这在 O (1)中运行,因此可以认为比您当前使用的更好。

答案 1 :(得分:3)

使用set跟踪看到的项目sets provide O(1) lookup

>>> item_list = [1, 7, 7, 7, 11, 14 ,100, 100, 4, 4, 4]
>>> seen = set()
>>> item_list[:] = [item for item in item_list
                                       if item not in seen and not seen.add(item)]
>>> item_list
[1, 7, 11, 14, 100, 4]

如果订单无关紧要,请在set()上使用item_list

>>> set(item_list)
set([1, 100, 7, 11, 14, 4])

答案 2 :(得分:2)

你的方式很棒! Set对于这类事情很有用,但如前所述,它们不维持秩序。其他写作方式更简洁,但可能不那么清楚,如下所示:

item_list.append(item) if item not in item_list else None

item_list += [item] if item not in item_list else []

如果您想添加多个new_items = [item1, ...],可以调整最后一个

item_list += [item for item in new_items if item not in item_list]

答案 3 :(得分:1)

如果您有多个地方要追加到集合中,那么编写if item not in item_list:....这样的样板代码不太方便,则您应该有一个单独的函数来跟踪对集合或子类列表的更改,并带有'append'方法覆盖:

class CollisionsList(list):
    def append(self, other):
        if other in self:
            raise ValueError('--> Value already added: {0}'.format(other))
        super().append(other)


l = CollisionsList()
l.append('a')
l.append('b')
l.append('a')
print(l)

答案 4 :(得分:0)

您可以使用如下所示的内置set()函数和list()函数将该设置对象转换为普通的python列表:

item_list = ['a','b','b']

print list(set(item_list))
#['a', 'b']

注意:使用集

时,不会保留订单

答案 5 :(得分:0)

当列表中有对象并且需要检查某个属性以查看其是否已在列表中时。

并不是说这是最好的解决方案,但是可以做到:

    def _extend_object_list_prevent_duplicates(list_to_extend, sequence_to_add, unique_attr):
        """
        Extends list_to_extend with sequence_to_add (of objects), preventing duplicate values. Uses unique_attr to distinguish between objects.
        """
        objects_currently_in_list = {getattr(obj, unique_attr) for obj in list_to_extend}
        for obj_to_add in sequence_to_add:
            obj_identifier = getattr(obj_to_add, unique_attr)
            if obj_identifier not in objects_currently_in_list:
                list_to_extend.append(obj_to_add)
        return list_to_extend