![](/img/trans.png)
[英]what is most pythonic way to find a element in a list that is different with other elements?
[英]What's the most pythonic way to ensure that all elements of a list are different?
我在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")
如果我必须用四个元素来做这件事,我会发疯的。
有没有更好的方法来确保列表中的所有元素都是唯一的?
也许是这样的:
if len(x) == len(set(x)):
print "all elements are unique"
else:
print "elements are not unique"
最流行的答案是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平方)不可避免(某些项目不可取,例如dicts,和一些不可比的,例如复数)。
这段代码的灵感来自于伟大的蒂姆·彼得斯(Tim Peters)的一个古老的食谱,它实际上产生了一系列独特的物品(而且到目前为止,这个set
还没有 - 它必须使用一个dict
......! - ),但基本上面临相同的问题。
这个怎么样:
if len(x) != len(set(x)):
raise Exception("throw to caller")
这假设x
中的元素是可清除的。
希望序列中的所有项目都是不可变的 - 如果不是,您将无法在序列上调用set
。
>>> set( ([1,2], [3,4]) )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
如果你确实有可变项,你不能散列项目,你几乎不得不反复检查列表:
def isUnique(lst):
for i,v in enumerate(lst):
if v in lst[i+1:]:
return False
return True
>>> isUnique( ([1,2], [3,4]) )
True
>>> isUnique( ([1,2], [3,4], [1,2]) )
False
在构建列表时,您可以检查值是否已存在,例如:
if x in y:
raise Exception("Value %s already in y" % x)
else:
y.append(x)
这样做的好处是会报告冲突变量。
您可以处理列表以创建已知的唯一副本:
def make_unique(seq):
t = type(seq)
seen = set()
return t(c for c in seq if not (c in seen or seen.add(c)))
或者如果seq元素不可清除:
def unique1(seq):
t = type(seq)
seen = []
return t(c for c in seq if not (c in seen or seen.append(c)))
这将使项目保持有序(当然,省略重复)。
我会用这个:
mylist = [1,2,3,4]
is_unique = all(mylist.count(x) == 1 for x in mylist)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.