至少有x个元素的不可变集合

3

我当前有这段代码,它检查数组中的所有元素是否相同。如果是这种情况,则返回true。

def all_equal(lst):
  """
  >>> all_equal([1,1,1,1,1,1,1])
  True
  >>> all_equal([1,2,3,1])
  False
  """
  return len(frozenset(lst)) == 1

但是我想要检查的是是否至少有5个相同的元素。

这样

[1,1,1,1,1,2,2]

同样也会返回True。因为有5个1。

4个回答

9
使用 collections.Counter()
from collections import Counter

def all_equal(lst, count):
    return any(v >= count for v in Counter(lst).values())

7

不要使用set,而是使用bagmultiset类型。multiset可以计算唯一值出现的次数。

在Python中,这就是collections.Counter()对象

from collections import Counter

def all_equal(lst):
    bag = Counter(lst)
    if any(v >= 5 for v in bag.itervalues()):
        # an element occurred at least 5 times
        # (use bag.values() if using Python 3)
        return True
    return False

但是即使它不是真的,它仍然返回True。 - Sharpless512
@Sharpless512:那么它 成立的情况是什么?请具体说明。 - Martijn Pieters
@Sharpless512:你的问题意味着你想要满足两个条件时返回true:要么只有一个唯一元素,或者至少有5个元素出现。这就是我编写的代码,如果不正确,你需要澄清你的问题。 - Martijn Pieters
只有在至少出现5次相同的元素时,它才应该返回True。 - Sharpless512
@Sharpless512:所以你想要忽略“只有一个唯一值”的情况?那么就简单地删除第一个if测试。请在你的问题中明确说明这一点,因为现在它看起来像是你想要将第二个测试添加到你现有的函数中。 - Martijn Pieters

3

使用Counter的简短答案:

from collections import Counter

def some_equal(lst):
    return max(Counter(lst).values()) >= 5
Counter 是一个“集合”,用于计算其元素的出现次数。 Counter.keys() 返回元素,Counter().values() 返回它们出现的次数。因此,这个max确保存在一个元素其出现次数超过5次。

2
max()会查看所有的值,而你可以在第一个大于等于5的值处停止。 - Eugene Yarmash
@eugeney 嗯,渐近复杂度是相同的 :) - Tigran Saluev

2
你可以在迭代时进行检查,如果任何值为 5,则可以短路:
from collections import defaultdict

def five(it):
    d  = defaultdict(int)
    for ele in it:
        d[ele] += 1
        if d[ele] == 5:
            return True
    return False

你可以使用Counter,但是仅仅计数defaultdict有时更快,甚至更快。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接