Answers:
不是最高效的,而是简单明了的:
if len(x) > len(set(x)):
pass # do something
短名单可能不会有太大的不同。
len(x) > len(set(x))
当其中的元素x
不是唯一时为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))
这是最快的方法。
s = set()
... 之后添加以下行来缩短此时间return not any(s.add(x) if x not in s else True for x in g)
len(x) != len(set(x))
不早退的情况会比现在更快吗?这两个操作不是O(len(x))吗?(x
原始列表在哪里)
if x in s
了O(len(x))的内部循环。
如何将所有条目添加到集合中并检查其长度呢?
len(set(x)) == len(x)
len()
。
完全使用排序和分组方式的另一种方法:
from itertools import groupby
is_unique = lambda seq: all(sum(1 for _ in x[1])==1 for x in groupby(sorted(seq)))
它需要排序,但是在第一个重复值上退出。
groupby
并找到了这个答案。我觉得这是最优雅的,因为这是一个表达式,可以与内置工具一起使用,而无需任何额外的变量或循环语句。
id()
函数对它们进行排序,因为这是工作的先决条件groupby()
:groupby(sorted(seq), key=id)
这是递归的提前退出函数:
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)
对于我来说,它足够快,而无需使用怪异的(慢速)转换,同时具有功能样式的方法。
H in T
进行线性搜索,并T = L[1:]
复制列表的切片部分,因此,这比在大列表上建议的其他解决方案要慢得多。我认为是O(N ^ 2),而其他大多数是O(N)(集合)或O(N log N)(基于排序的解决方案)。
您可以使用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))。这样会很快,而且还能保留订单。
x = range(1000000) + range(1000000)
,运行set(x)比f5(x)快。顺序不是问题的要求,但即使运行sorted(set(x))仍比f5(x)快
以上所有答案都很好,但我更喜欢使用30秒内的Pythonall_unique
示例
您需要set()
在给定列表上使用来删除重复项,并将其长度与列表的长度进行比较。
def all_unique(lst):
return len(lst) == len(set(lst))
True
如果平面列表中的所有值均为unique
,则返回,False
否则返回
x = [1,2,3,4,5,6]
y = [1,2,2,3,4,5]
all_unique(x) # True
all_unique(y) # False