Python入门-Collections

今天开始看《流畅的Python》,之前有很多时间没用Python,看这本书有一些吃力,每看一页都想回去好好看基础,一步步深入学习吧。

Collections是Python内建的一个集合模块,提供了许多有用的集合类。

1.namedtuple

在了解namedtuple之前回顾一下tuple,tuple(元组)与list十分类似,但tuple一旦被声明赋值就不可修改,初始化格式:p = (1,2,...),list是[]。而namedtuple看名字可以理解为有名字的元组,也就是可命名元组。元组有名字有什么好处呢?直接来用一下:

coordinate = namedtuple('Coordinate',['x','y']) #相当于定义了一个名为coordinate的元组 其中有两个字符串元素
co = coordinate(10,20)
print(co.x, co.y)   #通过名字访问
print(co[0],co[1])  #通过下标访问
10 20
10 20
可以看到namedtuple不仅可以通过下标获取值,也可以通过元素名获取,也就是我们自己给元素起的名字,在不确定索引的情况下用这种方法还是很方便的。namedtuple定义的格式是这个样子的:
collections.namedtuple(typename, field_names, [verbose=False], [rename=False])

第一个参数typename肯定就是这个namedtuple的名字了,不过好像也没有哪里用到了它,因为namedtuple实际上是个方法,有返回值的,名字叫什么其实无所谓,当然还是建议与变量名一致,也是有方法获取这个typename的:

print(coordinate.__name__)
field_names就是给元素定义的名字了,上面的例子是拿的别人的,是将元素都放在list中的(当然tuple也可以)。查了一下文档有其他的写法:
Student = namedtuple('Student', 'name serialnum school gradelevel') #写成'name,serialnum,...'也是可以的 可以说是很人性化了
s1 = Student(name = 'Jerry',serialnum='S001', school='JiaLiDun',gradelevel=3)
print(s1)
Student(name='Jerry', serialnum='S001', school='JiaLiDun', gradelevel=3)

Student有四个属性,用空格隔开,赋值的时候这样写也更清楚,这里切记赋值的时候需要对元组内每一个属性都赋值,否则会报错。

verbose:默认为False,冗长的,设为True会自动把详情步骤都打印出来,如果不是像我一样吃饱了没事干可以不用尝试了

rename:默认False,如果元素名称中含有python关键字,则必须设置为True

用到这边觉得namedtuple和字典差不多,不过字典突出的是键值关系,命名元组更有一点面向对象 类与属性的意味。

2.Counter

 学C语言的时候你一定遇到过这种题目让你统计一句话中的字符个数 ,Counter可以轻松做到,并返回一个字典。

c = Counter('hello Collections') #对字符进行计数
print(c)
c = Counter({'a':2,'b':5}) #可直接用字典创建
print(c)
c.update('aabab') #计数器更新update()
print(c)
c.update({'c':2}) #另一种更新方法
print(c)
Counter({'l': 4, 'o': 3, 'e': 2, 'h': 1, ' ': 1, 'C': 1, 'c': 1, 't': 1, 'i': 1, 'n': 1, 's': 1})
Counter({'b': 5, 'a': 2})
Counter({'b': 7, 'a': 5})
Counter({'b': 7, 'a': 5, 'c': 2})
除了update()方法更新,还有subtract()用来减去已有的或是没有的字符,为什么说可以减去没有的呢,因为这个value是负数也是ok的。
c = Counter({'a':2,'b':5})
c.subtract({'a':1,'c':1})
print(c)
elements()返回一个迭代器,你给Counter什么他就分门别类地排好给你,不过排列的先后并没有次序,当然它也不会对不存在的元素排列。
c = Counter('abccia')
print(list(c.elements())) #['a', 'a', 'b', 'g', 'c', 'i'] #['a', 'a', 'b', 'c', 'c', 'i']

most_common([n])返回一个列表,无参时将字符按照出现次数排列,有参代表出现次数最多的前n项。

print(c.most_common(2)) #[('a', 2), ('c', 2)]
iterkeys()与字典dict的keys方法类似,返回结果字典中所有key
itervalues()与字典dict的values方法类似,返回结果字典中的所有value

3.deque

list由于先进后出的特性,存储数据的优势在于按找索引查找元素会很快,但是插入和删除元素就很慢了,因为它是是单链表的数据结构。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈,而且线程安全。

list只提供了append和pop方法来从list的尾部插入/删除元素,但是deque新增了appendleft/popleft允许我们高效的在元素的开头来插入/删除元素。用法比较简单。

另外,rotate(n)方法很有意思,是将队列整体平移,n左负右正,队列整体长度不变。

4.OrderDict

Order(命令;顺序),OrderDict的意思是有序的字典,它是dict的一个子类。然后直接来用一下:
d = dict([('h',1),('a',3),('p',2),('y',1)])
print(d.keys())    #无序dict
d = OrderedDict(d)
print(d.keys()) #OrderedDict
好吧,看上去这两个结果根本没什么区别,于是跟着网上其他方法写了一下:
d = dict([('h',1),('a',3),('p',2),('y',1)]) #还是这个dict
print(d)    #无序dict
d = OrderedDict(sorted(d.items(), key=lambda t:t[0])) #用sorted()对key排序
print(d)    #OrderedDict([('a', 3), ('h', 1), ('p', 2), ('y', 1)])
d = OrderedDict(sorted(d.items(), key=lambda t:t[1])) #用sorted()对value排序
print(d) #OrderedDict([('h', 1), ('y', 1), ('p', 2), ('a', 3)])

貌似是有排序的效果了,但是!这和直接把dict sort一下有什么区别?不知道为什么我怎么试验都无法get到OrderDict的作用orz_

5.DefaultDict

默认字典,也是dict的一个子类。可以给dict没有key的元素定义初值,这很重要,因为dict对于不存在的键值访问是会报错的:

d0 = dict(lambda :0)
d0['a'] = 'abc'
print(d0['a'])
# print(d0['b']) 是报错的 
d = defaultdict(lambda :0) #定义默认value
d['k1'] = 'abc'
print(d['k1']) #abc
print(d['k2']) #0












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值