检查列表中的所有元素是否唯一的最佳方法(在传统方式中最好)是什么?
我目前使用Counter
的方法是:
>>> x = [1, 1, 1, 2, 3, 4, 5, 6, 2]
>>> counter = Counter(x)
>>> for values in counter.itervalues():
if values > 1:
# do something
我可以做得更好吗?
不是最有效,但直接和简洁:
if len(x) > len(set(x)):
pass # do something
可能不会对短名单产生太大影响。
这个怎么样
def is_unique(lst):
if not lst:
return True
else:
return Counter(lst).most_common(1)[0][1]==1
在Pandas数据框中使用类似的方法来测试列的内容是否包含唯一值:
if tempDF['var1'].size == tempDF['var1'].unique().size:
print("Unique")
else:
print("Not unique")
对我来说,这是一个包含超过一百万行的数据帧中的int变量的瞬间。
您可以使用Yan的语法(len(x)> len(set(x))),而不是set(x),定义一个函数:
def f5(seq, idfun=None):
# order preserving
if idfun is None:
def idfun(x): return x
seen = {}
result = []
for item in seq:
marker = idfun(item)
# in old Python versions:
# if seen.has_key(marker)
# but in new ones:
if marker in seen: continue
seen[marker] = 1
result.append(item)
return result
并执行len(x)> len(f5(x))。这将是快速的,也是订单保留。
对于初学者:
def AllDifferent(s):
for i in range(len(s)):
for i2 in range(len(s)):
if i != i2:
if s[i] == s[i2]:
return False
return True
这是一个双线,也将提前退出:
>>> def allUnique(x):
... seen = set()
... return not any(i in seen or seen.add(i) for i in x)
...
>>> allUnique("ABCDEF")
True
>>> allUnique("ABACDEF")
False
如果x的元素不可清除,那么你将不得不求助于使用seen
的列表:
>>> def allUnique(x):
... seen = list()
... return not any(i in seen or seen.append(i) for i in x)
...
>>> allUnique([list("ABC"), list("DEF")])
True
>>> allUnique([list("ABC"), list("DEF"), list("ABC")])
False
早期解决方案可能是
def unique_values(g):
s = set()
for x in g:
if x in s: return False
s.add(x)
return True
但是对于小病例或早期退出不是常见的情况,那么我希望len(x) != len(set(x))
是最快的方法。
速度:
import numpy as np
x = [1, 1, 1, 2, 3, 4, 5, 6, 2]
np.unique(x).size == len(x)
如何将所有条目添加到集合并检查其长度?
len(set(x)) == len(x)
替代set
,你可以使用dict
。
len({}.fromkeys(x)) == len(x)
完全另一种方法,使用sorted和groupby:
from itertools import groupby
is_unique = lambda seq: all(sum(1 for _ in x[1])==1 for x in groupby(sorted(seq)))
它需要排序,但退出第一个重复值。
这是一个递归的早退函数:
def distinct(L):
if len(L) == 2:
return L[0] != L[1]
H = L[0]
T = L[1:]
if (H in T):
return False
else:
return distinct(T)
对于我而言,在没有使用奇怪(慢)转换的同时具有功能风格的方法对我来说足够快。
这是一个有趣的递归O(N2)版本:
def is_unique(lst):
if len(lst) > 1:
return is_unique(s[1:]) and (s[0] not in s[1:])
return True