1. 程式人生 > >python 列表去重(不可變型別和可變型別)

python 列表去重(不可變型別和可變型別)

不可變型別

  • 利用set特性去重
ids = [1, 3, 8, 3, 8, 1, 9, 9, 9, 1]
ids = list(set(ids))
  • 新建一個list,迴圈遍歷
ids = [1, 3, 8, 3, 8, 1, 9, 9, 9, 1]
new_ids = []
for item in ids:
    if item not in new_ids:
        new_ids.append(item)
  • 使用reduce處理
ids = [1, 3, 8, 3, 8, 1, 9, 9, 9, 1]
func = lambda x, y: x if
y in x else x + [y] ids = reduce(func, [[], ] + ids)

可變型別

  • 用set處理
class A:
    def __init__(self, no, name):
        self.no = no
        self.name = name

    def __eq__(self, other):
        return self.no == other.no and self.name == other.name

    def __hash__(self):
        return hash(self.no) ^ hash(self.name)

    def
__repr__(self):
return str(self.no)+":"+self.name a_list = [A(1, "a"), A(2, "a"), A(1, "a"), A(1, "b")] a_list = list(set(a_list)) # a_list = [1:b, 2:a, 1:a] a_list.sort(key=lambda a: a.no) # 按no排序 a_list.sort(key=lambda a: a.name) # 按name排序

必須實現”__eq__”和”__hash__”方法。
“__eq__”用於判斷是否相等,”__hash__”用於計算hash值。
因為set存取的必須是不可變型別,它是依賴”__hash__”來計算桶的位置,而利用”__eq__”來判斷元素之間是否相等。
關於其更多的介紹:

https://segmentfault.com/a/1190000003969462

  • 新建一個list,迴圈遍歷
class A:
    def __init__(self, no, name):
        self.no = no
        self.name = name

    def __eq__(self, other):
        return self.no == other.no and self.name == other.name

    def __repr__(self):
        return str(self.no)+":"+self.name

a_list = [A(1, "a"), A(2, "a"), A(1, "a"), A(1, "b")]
new_a_list = []
for a in a_list:
    if a not in new_a_list:
        new_a_list.append(a)

注意這裡實現了”__eq__”方法,才能使得“if a not in new_a_list:”語句生效。

  • 使用字典dict記錄
    如果不想實現”__eq__”方法,且元素存在”主鍵”屬性(根據其區分物件相等不相等),則可以使用字典dict來記錄列表元素出現與否(置0或1),然後遇到非0的就刪除該元素即可。
class A:
    def __init__(self, no, name):
        self.no = no
        self.name = name

    def __repr__(self):
        return str(self.no)+":"+self.name


# no為"主鍵"
a_list = [A(1, "a"), A(2, "b"), A(1, "a"), A(3, "b")]
mp = {}

for a in a_list:
    if a.no not in mp:
        mp[a.no] = 1
    else:
        mp[a.no] += 1
        a_list.remove(a)