如何确保列表中所有元素都不同的最Pythonic方式是什么?

8 投票
7 回答
669 浏览
提问于 2025-04-15 14:43

我在Python中有一个列表,这是我程序的一部分生成的。我很确定这些元素都是不同的,所以我用一种方式来检查这一点。

这是我现在的做法:

如果列表里有两个元素:

try:
    assert(x[0] != x[1])
except:
    print debug_info
    raise Exception("throw to caller")

如果有三个元素:

try:
    assert(x[0] != x[1])
    assert(x[0] != x[2])
    assert(x[1] != x[2])
except:
    print debug_info
    raise Exception("throw to caller")

如果我还要处理四个元素,我可能会疯掉。

有没有更好的方法来确保列表中的所有元素都是唯一的呢?

7 个回答

7

这样怎么样:

if len(x) != len(set(x)):
    raise Exception("throw to caller")

这里假设 x 中的元素是可以被哈希的。

18

最受欢迎的答案是 O(N)(不错!),但正如 @Paul 和 @Mark 指出的那样,这要求列表中的项目是可哈希的。@Paul 和 @Mark 提出的针对不可哈希项目的方法是通用的,但效率较低,达到 O(N²)——也就是非常耗时。

如果你的列表项目不可哈希,但可以进行比较,你可以做得更好……这里有一个方法,可以在考虑列表项目特性的情况下,尽可能快地工作。

import itertools

def allunique(L):
  # first try sets -- fastest, if all items are hashable
  try:
    return len(L) == len(set(L))
  except TypeError:
    pass
  # next, try sort -- second fastest, if items are comparable
  try:
    L1 = sorted(L)
  except TypeError:
    pass
  else:
    return all(len(list(g))==1 for k, g in itertools.groupby(L1))
  # fall back to the slowest but most general approach
  return all(v not in L[i+1:] for i, L in enumerate(L))

在可行的情况下,这是 O(N)(所有项目都是可哈希的),在大多数情况下是 O(N log N)(一些项目不可哈希,但所有项目都可以比较),在不可避免的情况下是 O(N²)(一些项目不可哈希,比如字典,还有一些不可比较的项目,比如复数)。

这段代码的灵感来自伟大的 Tim Peters 的一个旧配方,那个配方实际上是生成一个唯一项目的列表(而且那时候还没有 set,只能用 dict...!),但基本上面临着相同的问题。

26

也许可以这样做:

if len(x) == len(set(x)):
    print "all elements are unique"
else:
    print "elements are not unique"

撰写回答