我需要一个函数,它接受一个列表并输出True,如果输入列表中的所有元素使用标准相等运算符计算彼此相等,否则输出False。
我觉得最好是遍历列表,比较相邻的元素,然后与所有结果布尔值。但我不知道最python的方法是什么。
我需要一个函数,它接受一个列表并输出True,如果输入列表中的所有元素使用标准相等运算符计算彼此相等,否则输出False。
我觉得最好是遍历列表,比较相邻的元素,然后与所有结果布尔值。但我不知道最python的方法是什么。
当前回答
这是另一个选项,对于长列表,比len(set(x))==1快(使用短路)
def constantList(x):
return x and [x[0]]*len(x) == x
其他回答
最佳答案
Twitter上有一个不错的帖子,介绍了实现all_equal()函数的各种方法。
给定一个列表输入,最好的提交是:
t.count(t[0]) == len(t)
其他方法
下面是线程的结果:
Have groupby() compare adjacent entries. This has an early-out for a mismatch, does not use extra memory, and it runs at C speed. g = itertools.groupby(s) next(g, True) and not next(g, False) Compare two slices offset from one another by one position. This uses extra memory but runs at C speed. s[1:] == s[:-1] Iterator version of slice comparison. It runs at C speed and does not use extra memory; however, the eq calls are expensive. all(map(operator.eq, s, itertools.islice(s, 1, None))) Compare the lowest and highest values. This runs at C speed, doesn't use extra memory, but does cost two inequality tests per datum. min(s) == max(s) # s must be non-empty Build a set. This runs at C speed and uses little extra memory but requires hashability and does not have an early-out. len(set(t))==1. At great cost, this handles NaNs and other objects with exotic equality relations. all(itertools.starmap(eq, itertools.product(s, repeat=2))) Pull out the first element and compare all the others to it, stopping at the first mismatch. Only disadvantage is that this doesn't run at C speed. it = iter(s) a = next(it, None) return all(a == b for b in it) Just count the first element. This is fast, simple, elegant. It runs at C speed, requires no additional memory, uses only equality tests, and makes only a single pass over the data. t.count(t[0]) == len(t)
不管怎样,这是最近在python想法邮件列表中出现的。事实证明,已经有一个itertools配方可以做到这一点
def all_equal(iterable):
"Returns True if all the elements are equal to each other"
g = groupby(iterable)
return next(g, True) and not next(g, False)
据说它的性能非常好,有一些不错的属性。
短路:一旦发现第一个不相等的项,它就会停止从可迭代对象中消费项目。 不要求项是可哈希的。 它是懒惰的,只需要O(1)个额外的内存来进行检查。
换句话说,我不能把提出这个解决方案的功劳占为己有,甚至我也不能把找到它的功劳占为己有。
也许我低估了问题的严重性?检查列表中唯一值的长度。
lzt = [1,1,1,1,1,2]
if (len(set(lzt)) > 1):
uniform = False
elif (len(set(lzt)) == 1):
uniform = True
elif (not lzt):
raise ValueError("List empty, get wrecked")
比使用set()处理序列(而不是可迭代对象)更快的解决方案是简单地计算第一个元素。这假设列表是非空的(但这是微不足道的检查,并决定什么结果应该在一个空列表)
x.count(x[0]) == len(x)
一些简单的基准:
>>> timeit.timeit('len(set(s1))<=1', 's1=[1]*5000', number=10000)
1.4383411407470703
>>> timeit.timeit('len(set(s1))<=1', 's1=[1]*4999+[2]', number=10000)
1.4765670299530029
>>> timeit.timeit('s1.count(s1[0])==len(s1)', 's1=[1]*5000', number=10000)
0.26274609565734863
>>> timeit.timeit('s1.count(s1[0])==len(s1)', 's1=[1]*4999+[2]', number=10000)
0.25654196739196777
你可以:
reduce(and_, (x==yourList[0] for x in yourList), True)
python让你导入operator.and_这样的操作符是相当烦人的。从python3开始,还需要导入functools.reduce。
(您不应该使用此方法,因为如果它发现不相等的值,它不会中断,而是会继续检查整个列表。这里只是作为完整性的回答。)