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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值