目录
描述
Python列表方法count用于统计特定值在列表中的出现次数。
语法和参数
list.count(element)
名称 | 含义 |
element | 列表中统计的对象 |
返回值
int。list.count方法返回参数元素在列表中的数量。
使用示例
if __name__ == '__main__':
demo = ["a", "p", "p", "l", "e"]
print(demo.count("p"))
# output: 2
注意事项
要查询的元素在列表中不存在时
当要查询的元素在列表中不存在时,count元素返回0。
>>> demo = ["a", "b", "c"]
>>> demo.count("aa")
0
原理
list.count方法与str.count方法类似,都是统计某个元素/字符串在列表/字符串中出现的次数,但list.count方法更复杂,因为它不仅仅是比较字符串类型的元素。在Python中,一个列表内可以包括任意类型的元素,除了基本类型外,还可以是其它Python类对象的实例。下面我们看一个例子:
class Student(object):
def __init__(self, name):
self.name = name
if __name__ == '__main__':
s1 = Student("xiaoming")
s2 = Student("Mike")
l = [s1, s2]
s3 = Student("Mike")
print(l.count(s3))
# output: 0
上面的代码中定义了一个Student类。这个类接受一个name参数用来表示学生的名字。列表l中存在两个学生s1:xiaoming 和s2:Mike。现在我们创建第三个学生s3,他与s2同名,也叫Mike。现在我们使用count方法统计下列表中s3的数量,但是count方法返回为0。
count方法的原理是依次比较参数s3与列表中的元素是否相等(与使用==号的意义相同),虽然s2.name 与 s3.name是相同的值,但s2与s3并不是一个对象,因此count方法返回0。因此我们可以这样稍作修改:
class Student(object):
def __init__(self, name):
self.name = name
if __name__ == '__main__':
s1 = Student("xiaoming")
s2 = Student("Mike")
l = [s1, s2]
s3 = s2
print(l.count(s3))
# output: 1
在这次的修改中,s3与s2代表着相同的对象实例,所以count方法返回1。如果我们想使用count方法统计出列表中即便不是相同对象,但只要name相同的元素数量怎么办?我们可以通过重写__eq__方法来达到效果:
class Student(object):
def __init__(self, name):
self.name = name
def __eq__(self, other):
return isinstance(other, Student) and self.name == other.name
if __name__ == '__main__':
s1 = Student("xiaoming")
s2 = Student("Mike")
l = [s1, s2]
s3 = Student("Mike")
print(l.count(s3))
# outputs: 1
即便s3与s2不是同一个实例对象,但count方法的结果是1。
通过上面的问题,我们搞清了count方法的原理其实就是调用__eq__方法的结果来判断是否相等。我们看下面的例子。s1和s2是Student类的实例,s3是Student2类的实例。那么调用list.count方法时,最终调用的是列表元素的__eq__方法:
class Student(object):
def __init__(self, name):
self.name = name
def __eq__(self, other):
print("inner Student.__eq__")
return isinstance(other, Student) and self.name == other.name
class Student2(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
print("inner Student2.__eq__")
return isinstance(other, Student2) and self.age == other.age
if __name__ == '__main__':
s1 = Student("xiaoming")
s2 = Student("Mike")
l = [s1, s2]
s3 = Student2("Mike", 23)
print(l.count(s3))
# outputs:
# inner Student.__eq__
# inner Student.__eq__
# 0
我们继续改变一下示例代码。如果Student2是Student类的子类,那么使用list.count方法,最终调用的是参数的__eq__方法:
class Student(object):
def __init__(self, name):
self.name = name
def __eq__(self, other):
print("inner Student.__eq__")
return isinstance(other, Student) and self.name == other.name
class Student2(Student):
def __init__(self, name, age):
Student.__init__(self, name)
self.age = age
def __eq__(self, other):
print("inner Student2.__eq__")
return isinstance(other, Student2) and self.age == other.age
if __name__ == '__main__':
s1 = Student("xiaoming")
s2 = Student("Mike")
l = [s1, s2]
s3 = Student2("Mike", 23)
print(l.count(s3))
# outputs:
# inner Student2.__eq__
# inner Student2.__eq__
# 0
综上所述,关于count的原理我们可以总结如下:
- list.count方法返回参数在列表中的数量。返回值是一个整数类型。
- list.count方法的时间复杂度为
(假设__eq__的时间复杂度是
),即参数要跟列表中的每一个元素进行比较。
- 参数与列表中元素进行比较时,本质上是调用类的__eq__方法。如果参数跟列表中的元素是同一个类的对象,那么比较是调用该类的__eq__方法;如果参数跟列表中的元素是不同类的对象,但类之间属于继承关系,那么调用的是子类的__eq__方法;如果参数跟列表中的元素是不同类的对象,且类之间不属于继承关系,那么调用列表元素所属类的__eq__方法。