Python中List的去重问题

Python中的去重问题,这或许是个简单的问题。

比如一个list:a = [1,3,2,9,5,3,1,5],如何删除重复元素,嗯,有一个高端的方法:

#方法一

a = set(a)

a:1, 2, 3, 5, 9.哇,好高端,事情可没这么简单,观察,a的顺序变的,类型也变了

print a,type(a)

set([1, 2, 3, 5, 9]) <type 'set'>

a变成了python里面的集合类型,顺序且无重复元素,跟sort的功能有点类似,好用,但是这个上述方法既改变的a的类型又改变了a中元素既有顺序(虽然用类型转换成将a变为list类型。

注意a里面的元素全是数字,如果将a里面有其它元素比如:

a = [1,3,2,9,5,3,1,5,[1,2],[1,2]]

print set(a)

TypeError: unhashable type: 'list'

于是发现set这个方法不好使了,原因是a里面出现了不可哈希的元素类型,那何为可哈希元素呢?

python文档里面是这么说的:

An object ishashable if it has a hash value which never changes duringits lifetime (it needs a__hash__() method), and can be compared to other objects (it needs an__eq__() or __cmp__() method). Hashable objects which compare equal must have the same hash value.

意思就是说生存期内存可变的对象不可哈希,像list,dict就是不可哈希的,因为它们是可变对象,tuple和str就是不可变对象,是可哈希的。

因此,这个问题产生的原因在于不能想当然地认为list中的元素都是可哈希的,这并不是一个通用的解决方案

#方法二

再看另一种方法,用函数。

from collections import Counter
a = [1,3,2,9,5,3,1,5]
c = Counter(a)
print c

 输了结果为:

Counter({1: 2, 3: 2, 5: 2, 2: 1, 9: 1})

这不错,将a中的每个元素的个数都列举出来了,这样的话只需要根据c元素与之对应的元素个数删除重复元素即可(c的类型为Counter,可以看出跟dict类型相似,用法也是相似的)

c = {k:v-1 for k,v in c.items() if v > 1}#将a中元素个数大于1的元素找出来,v-1表示要删除的重复元素的个数
for k,v in c.items():
    for i in range(v):#根据重复次数删除重复元素
        a.remove(k)

如此便可达到去重的目的,貌似有点复杂哦。

看到有网友用这个方法:

a = sorted(set(a),key = a.index)

矮小精悍,很不错哦

但是这些方法同样不支持不可哈希对象的操作,因此这个方法也不具有通用性。

#方法三

那只有最笨的方法了

c = {a.count(a[i]):a[i] for i in xrange(len(a))}

然后套用方法二即可,在运用这个方法的过程中,发现dict类型为key:value的形式,其中key的值只能为可哈希元素,又引申出一个新的问题,回头再读一读陈儒写的python源码剖析,呵呵!

未完,待续……

  

posted @ 2018-04-07 10:40  zxf123  阅读(302)  评论(0编辑  收藏  举报