使用collections.Counter,得到计数为1的:
from collections import Counter
def find_uniq(arr):
c = Counter(arr)
return [number for number,count in c.most_common() if count == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
这大约需要 O(2*n) 所以 O(n) 因为 2 是常数。
collection.defaultdict with int,得到计数为 1 的:
# defaultdict
from collections import Counter , defaultdict
def find_uniq(arr):
c = defaultdict(int)
for a in arr:
c[a] += 1
return [number for number,count in c.items() if count == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
这大约需要 O(2*n) 所以 O(n) 因为 2 是恒定的 - 由于实现内部的 C 优化,它比 Counter 稍微快一点(参见 f.e. Surprising results with Python timeit: Counter() vs defaultdict() vs dict())。
normal dicts 和 setdefault 或 test/add,获取计数为 1 的:
# normal dict - setdefault
def find_uniq(arr):
c = dict()
for a in arr:
c.setdefault(a,0)
c[a] += 1
return [number for number,count in c.items() if count == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
# normal dict - test and add
def find_uniq(arr):
c = dict()
for a in arr:
if a in c:
c[a] += 1
else:
c[a] = 1
return [number for number,count in c.items() if count == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
Setdefault 每次都会创建默认值 - 它比 Counter 或 defaultdict 慢,比使用 test/add 快。
itertools.groupby(需要排序列表!),获取计数为1的:
from itertools import groupby
def find_uniq(arr):
return [k for (k,p) in groupby(sorted(arr)) if len(list(p)) == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
groupby 需要一个排序列表,单独的列表排序是 O(n * log n) 并且结合起来这比其他方法慢。