从列表中移除重复元素,但仅限于奇数个重复的元素
我想从一个列表中去掉那些出现次数是奇数的重复元素。举个例子,对于这个列表:[1, 2, 3, 3, 3, 5, 8, 1, 8]
,数字1出现了2次,数字3出现了3次,数字8也出现了2次。所以1和8应该被去掉,而数字3只保留1个。
这是我想到的解决方法:
def remove_odd_duplicates(arr):
h = {}
for i in arr:
if i in h:
h[i] += 1
else:
h[i] = 1
arr = []
for i in h:
if h[i] % 2:
arr.append(i)
return arr
这个方法返回的结果是正确的:[2, 3, 5]
,但我觉得可以用更好的方式来写。有没有什么好的建议呢?
3 个回答
1
你可以试试用 scipy.stats.itemfreq
这个工具:
>>> from scipy.stats import itemfreq
>>> xs = [1, 2, 3, 3, 3, 5, 8, 1, 8]
>>> ifreq = itemfreq(xs)
>>> ifreq
array([[1, 2],
[2, 1],
[3, 3],
[5, 1],
[8, 2]])
>>> i = ifreq[:, 1] % 2 != 0
>>> ifreq[i, 0]
array([2, 3, 5])
2
如果顺序不重要:
>>> a = [1, 2, 3, 3, 3, 5, 8, 1, 8]
>>> list(set([x for x in a if a.count(x)%2 == 1]))
[2, 3, 5]
这个列表推导式 [x for x in a if a.count(x)%2 == 1]
只会返回那些在列表中出现奇数次的元素。list(set(...))
是一种常见的方法,用来去掉列表中的重复项。
4
你可以使用 collections.Counter
和列表推导式,像这样:
data = [1, 2, 3, 3, 3, 5, 8, 1, 8]
from collections import Counter
print [item for item, count in Counter(data).items() if count % 2]
# [2, 3, 5]
Counter
会生成一个字典,字典里的每个元素都是你输入的可迭代对象中的键,而它们对应的值就是出现的次数。所以,我们遍历这个字典,检查每个元素的出现次数是否是奇数,然后只保留那些奇数的元素。
注意:这个方法的复杂度还是 O(N),和你最开始的程序是一样的。