这一个月好像干了好多事,又好像什么也没干,python也没有理解的很透,高数也是一团糟,大一第一学期才刚过半,就到迷茫期了(我好像一直很迷茫,自从开学,我就不知道自己到底想要干什么,那天部长问我我有什么打算,我愣住了,在开学前我信誓旦旦的说我以后要做一个优秀的程序员,做出惊天动地的AI,但是,最近的我好像不知道应该做什么,心里只想着走一步算一步),不管怎么样,重整旗鼓,好好学习。
Python 除了基本的 list ,dict ,tuple ,set 等数据结构外,还提供了一个强大模块: collections 。模块提供了许多有用的集合类,灵活使用它们能提高我们使用 Python 编程的效率。
一、命名元组 (namedtuple)
创建命名元组
命名元组的构造函数接受两个参数typename,field_names:
- typename:元组的名字;
- field_names:元组各个元素的名称,也就是属性名称。
collections.namedtuple("Point",["x","y"])
这样就创建了一个叫做Point的命名元组类,它拥有两个属性x,y。
第二个参数["x","y"]也可以写成"x y"或者"x,y",即用空格或者逗号隔开属性名,即:
我们可以将其赋值给一个变量:
- Point = collections.namedtuple("Point","x,y")
- p = collections.namedtuple("Point","x,y") #变量名不一定要和第一个参数相同
以上得到的变量Point或者p并不直接是一个元组对象,它只是一个类,如果要创建它的实例,则需要像创建类实例一样调用它:
- p1 = Point(x = 0, y = 0)
- p2 = p(x = 1, y = 1)
这样就创建了两个实例p1,p2,他们的内容分别是x = 0,y = 0,x = 1,y = 1。
访问命名元组的元素
通过collections.namedtuple创建的命名元组类,实际上是元组类的子类,因此命名元组也可以通过索引访问元素:
- print(p1[0])
- print(p1[1])
得到的结果: 0 0
当然,命名元组也可以通过属性访问:
collections.namedtuple("Point","x y")
collections.namedtuple("Point","x,y")
print(p2.x)
print(p2.y)
得到的结果: 1 1
修改元素
如果需要修改元组的元素,则不能简单的使用p1.x = 1,需要调用成员函数_replace(),它会返回一个包含新值的新实例,比如:
p1 = p1._replace(x = 1) #将p1的x值从0换到1
二、计数器(Counter)
计数器是一个无序容器,用于记录各种值出现的次数。它采用键值对的形式存储,要记录的值作为key,这个值出现的次数作为value,value值可正可负。 ##创建计数器 要创建一个计数器实例,可以调用它的无参构造函数:
c = collections.Counter()
这样就创建了一个空的计数器实例c。
也可以从list,tuple,dict,字符串等**可迭代对象(iterable)**创建:
c = collections.Counter(['a','a','b','b','c']) #从list创建
c = collections.Counter(('a','a','b','b','c')) #从tuple创建
c = collections.Counter({'a':2,'b':2,'c':1}) #从dict创建
c = collections.Counter("aabbc") #从字符串创建
上面四条语句创建出来的计数器c都是相同的: {'a': 2, 'b': 2, 'c': 1}
最后,你也可以直接指定键值对,来创建计数器:
c = collections.Counter(a=2,b=2,c=1)
创建出来的计数器c,与上面四条语句创建的计数器c是相同的。 #####访问元素 计数器是dict的子类,因此可以像使用dict那样访问计数器元素:
- print(c['a'])
- print(c['b'])
- print(c.c)
得到的结果是:
2
2
1
不过与dict不同的是,当访问计数器中不存在的元素的时候,不会产生异常,而是返回0,比如:
print(c['d']) #c中没有d元素,但不会发生异常
上面的代码能够正常运行,并且结果是:0
增加计数与减少计数
要改变计数器中某一元素的值,除了可以使用操作dict的方式:c.a = XXX外,计数器还提供了两个成员函数update和subtfract。
update函数接受一个可迭代对象,然后将这个对象中各种值出现的次数加到计数器中,比如
c.update("aabbcd") #字符串也是可迭代对象
上面这行语句执行后,c的值从原来的: {'a': 2, 'b': 2, 'c': 1} 增加到了: {'a': 4, 'b': 4, 'c': 2, 'd': 1}
subtract函数与update函数类似,不过它是从计数器中减去可迭代对象中各种值出现的次数,比如:
c.subtract("aabbcd")
上面这行语句执行后,c的值从原来的: {'a': 4, 'b': 4, 'c': 2, 'd': 1} 减少到了: {'a': 2, 'b': 2, 'c': 1, 'd': 0}
删除元素
从上面的例子可以发现,当计数器中一个元素的值减少到0时,它并不会自动从计数器中删除,如果要删除元素,可以使用del函数:
del(c['d'])
上面这行语句执行后,c的值从原来的: {'a': 2, 'b': 2, 'c': 1, 'd': 0} 变成了: {'a': 2, 'b': 2, 'c': 1} 即元素d被删除了。
TopN操作
计数器还提供了一个获取出现次数最多的n个元素的成员函数most_common,它返回包含这些元素的list,比如:
top1 = c.most_common(1) #出现次数最多的元素
print(top1)
top2 = c.most_common(2) #出现次数最多的两个元素
print(top2)
all = c.most_common() #不提供参数则返回所有元素
print(all)
得到的结果是: [('a', 2)] [('a', 2), ('b', 2)] [('a', 2), ('b', 2), ('c', 1)]
注意:如果有多个元素的值相同,那么它们之间的顺序是不可确定的,不要在它们的顺序上作任何假设。



