首页 > Python > Python  检查列表中的所有元素是否相同

Python  检查列表中的所有元素是否相同

上一篇 下一篇

我需要一个函数,如果输入列表中的所有元素都使用标准相等运算符和其他方式评估为彼此相等,则它接受 a 并输出。listTrueFalse

我觉得最好遍历列表,比较相邻元素,然后比较所有生成的布尔值。但我不确定什么是最Pythonic的方式。AND

分割线

网友回答:

使用(见食谱):itertools.groupbyitertools

from itertools import groupby

def all_equal(iterable):
    g = groupby(iterable)
    return next(g, True) and not next(g, False)

或不 :groupby

def all_equal(iterator):
    iterator = iter(iterator)
    try:
        first = next(iterator)
    except StopIteration:
        return True
    return all(first == x for x in iterator)

您可以考虑使用多种替代单行代码:

  1. 将输入转换为集合并检查它是否只有一个或零个(如果输入为空)项目
    def all_equal2(iterator):
        return len(set(iterator)) <= 1
    
  2. 与没有第一项的输入列表进行比较
    def all_equal3(lst):
        return lst[:-1] == lst[1:]
    
  3. 计算第一项在列表中出现的次数
    def all_equal_ivo(lst):
        return not lst or lst.count(lst[0]) == len(lst)
    
  4. 与重复的第一个元素的列表进行比较
    def all_equal_6502(lst):
        return not lst or [lst[0]]*len(lst) == lst
    

但它们有一些缺点,即:

  1. all_equal并且可以使用任何迭代器,但其他迭代器必须采用序列输入,通常是列表或元组等具体容器。all_equal2
  2. all_equal并在发现差异后立即停止(所谓的“短路”),而所有替代方案都需要遍历整个列表,即使您可以通过查看前两个元素来判断答案。all_equal3False
  3. 在内容必须是可哈希的。例如,列表列表将引发一个。all_equal2TypeError
  4. all_equal2(在最坏的情况下)并创建列表的副本,这意味着您需要使用双倍的内存。all_equal_6502

在 Python 3.9 上,使用 ,我们得到这些计时(越低越好):perfplotRuntime [s]

for a list with a difference in the first two elements, groupby is fastestfor a list with no differences, count(l[0]) is fastest

分割线

网友回答:

比使用适用于序列(不是可迭代对象)的 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

分割线

网友回答:

[编辑:这个答案稍后解决了目前投票最多(这是一个很好的答案)的答案。itertools.groupby

在不重写程序的情况下,最渐近性能和最易读的方式如下:

all(x==myList[0] for x in myList)

(是的,这甚至适用于空列表!这是因为这是python具有惰性语义的少数情况之一。

这将在尽可能早的时间失败,因此它是渐近最优的(预期时间大约是O(#uniques)而不是O(N),但最坏情况的时间仍然是O(N))。这是假设您以前没有看过数据…

(如果你关心性能,但不太关心性能,你可以先做通常的标准优化,比如把常量吊出循环,为边缘情况添加笨拙的逻辑,尽管这是python编译器最终可能会学会怎么做的事情,因此除非绝对必要,否则不应该这样做, 因为它破坏了可读性,以获得最小的收益。myList[0]

如果您更关心性能,这是上述速度的两倍,但更详细一些:

def allEqual(iterable):
    iterator = iter(iterable)
    
    try:
        firstItem = next(iterator)
    except StopIteration:
        return True
        
    for x in iterator:
        if x!=firstItem:
            return False
    return True

如果你更关心性能(但不足以重写你的程序),请使用当前投票最多的答案,它的速度是它的两倍,因为它可能是优化的 C 代码。(根据文档,它应该(类似于这个答案)没有任何内存开销,因为惰性生成器永远不会被评估到列表中……哪一个可能会担心,但伪代码显示分组的“列表”实际上是惰性生成器。itertools.groupbyallEqual

如果您更关心性能,请继续阅读…


关于性能的旁注,因为其他答案出于某种未知原因在谈论它:

…如果您以前看过数据并且可能使用某种类型的集合数据结构,并且您真的很关心性能,那么您可以通过使用计数器来免费获得 .isAllEqual() O(1),该计数器会随着每次插入/删除/等操作而更新,只需检查它是否为 {something:someCount}len(counter.keys())==1;或者,您可以在单独的变量中保留一个计数器。事实证明,这比其他任何恒定因素都要好。也许你也可以使用python的FFI与你选择的方法一起使用,也许也可以使用启发式方法(比如,如果它是一个带有getitem的序列,然后检查第一个元素,最后一个元素,然后按顺序检查元素)。ctypes

当然,为了可读性,有一些话要说。

模板简介:该模板名称为【Python  检查列表中的所有元素是否相同】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【Python】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 166次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 04-08
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
单页式简历模板 html5 微信图片 响应式 微信文章 微信公众平台 企业网站 微信素材 自适应 微信模板
您可能会喜欢的其他模板