检查列表中的所有元素是否唯一
检查列表中的所有元素是否都是唯一的最好的方法是什么(与传统方式一样)?
我现在使用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 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
早期退出的解决scheme可能是
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)
替代set
,你可以使用dict
。
len({}.fromkeys(x)) == len(x)
如何将所有条目添加到一个集合并检查其长度?
len(set(x)) == len(x)
这是一个recursion的早期退出函数:
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)
对于我来说,速度够快,而不需要使用奇怪(缓慢)的转换,而采用function风格的方法。
这个怎么样
def is_unique(lst): if not lst: return True else: return Counter(lst).most_common(1)[0][1]==1
另一种方法完全使用sorting和groupby:
from itertools import groupby is_unique = lambda seq: all(sum(1 for _ in x[1])==1 for x in groupby(sorted(seq)))
它需要一个sorting,但在第一个重复的价值退出。
这是一个recursion的O(N 2 )版本的乐趣:
def is_unique(lst): if len(lst) > 1: return is_unique(s[1:]) and (s[0] not in s[1:]) return True
在Pandas数据框中使用类似的方法来testing列的内容是否包含唯一值:
if tempDF['var1'].size == tempDF['var1'].unique().size: print("Unique") else: print("Not unique")
对我来说,这是一个包含超过一百万行的date框架中的intvariables的即时。
你可以使用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))。 这将是快速的,也是保持秩序。
代码取自: http : //www.peterbe.com/plog/uniqifiers-benchmark
对于成鸽:
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