collection库笔记

collections 模块包含了一些特殊的容器,针对Python内置的容器,例如list、dict、set和tuple,提供了另一种选择;

计数器(Counter)

dict的子类,计算可hash的对象

Counter可以支持方便、快速的计数

from collections import  Counter

str="abcbcaccbbad"
li=[2,3,43,3,45,54,33,33,1]
d={'d':3,'f':4,'g':3,'h':5}

#获取元素个数,返回字典,返回的字典是无序的,**不是按照降序或者升序排序的**
print(Counter(str))
print(dict(Counter(d))) # 转换为常见的字典形式
print(dict(Counter(li)))

#获取key和value
print(list(Counter(str).items())) # 字典的key和value
print(list(Counter(str).keys())) # 字典的key
print(list(Counter(str).values())) # 字典的value
输出:
Counter({'b': 4, 'c': 4, 'a': 3, 'd': 1})
{'d': 3, 'f': 4, 'g': 3, 'h': 5}
{2: 1, 3: 2, 43: 1, 45: 1, 54: 1, 33: 2, 1: 1}

[('a', 3), ('b', 4), ('c', 4), ('d', 1)]
['a', 'b', 'c', 'd']
[3, 4, 4, 1]

[('b', 4), ('c', 4)]
[('b', 4), ('c', 4), ('a', 3), ('d', 1)]

aaabbbbccccd

{'a': 4, 'b': 4, 'c': 4, 'd': 1, 's': 2, '1': 1}

{2: 0, 3: 1, 43: 1, 45: 1, 54: 1, 33: 2, 1: 1}
Counter({33: 2, 3: 1, 43: 1, 45: 1, 54: 1, 1: 1, 2: 0})

Counter对象支持三个字典不支持的方法:elements(),most_common(),subtract()

element()

返回一个迭代器,每个元素重复的次数为它的数目,顺序是任意的顺序,如果一个元素的数目少于1,那么elements()就会忽略它

print(list(Counter(str).elements())) # ['a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'd']

most_common()

返回一个列表,包含counter中n个最大数目的元素,如果忽略n或者为None,most_common()将会返回counter中的所有元素,元素有着相同数目的将会以任意顺序排列

print(Counter(str).most_common(2))  # [('b', 4), ('c', 4)]
print(Counter(str).most_common()) # [('b', 4), ('c', 4), ('a', 3), ('d', 1)]
print(Counter(str).most_common(None))  # [('b', 4), ('c', 4), ('a', 3), ('d', 1)]

subtract()

从一个可迭代对象中或者另一个映射(或counter)中,元素相减,类似于dict.update(),但是subtracts 数目而不是替换它们,输入和输出都有可能为0或者为负

c = Counter(a=4,b=2,c=0,d=-2)
d = Counter(a=1,b=2,c=-3,d=4)
c.subtract(d)
print(c) # Counter({'a': 3, 'c': 3, 'b': 0, 'd': -6})

update()

从一个可迭代对象中或者另一个映射(或counter)中所有元素相加,类似于dict.upodate,是数目相加而非替换它们,另外,可迭代对象是一个元素序列,而非(key,value)对构成的序列

c = Counter(a=4,b=2,c=0,d=-2)
d = Counter(a=1,b=2,c=-3,d=4)
c.update(d)
print(c)  # Counter({'a': 5, 'b': 4, 'd': 2, 'c': -3})

Counter对象类似于字典,如果某个项缺失,会返回0,而不是报出KeyError

from collections import  Counter
c = Counter(['eggs','ham'])
print(c['bacon'])#没有'bacon'
print(c['eggs'])#有'eggs'
输出:
0
1

删除

将一个元素的数目设置为0,并不能将它从counter中删除,使用del可以将这个元素删除

print(c)
c['eggs'] = 0
print(c)
del c['eggs']
print(c)
Counter({'eggs': 1, 'ham': 1})
Counter({'ham': 1, 'eggs': 0})
Counter({'ham': 1})
c = Counter(a=3,b=1,c=-2)
d = Counter(a=1,b=2,c=4)
print(c+d) # 求和,Counter({'a': 4, 'b': 3, 'c': 2})
print(c-d) # 求差,Counter({'a': 2})
print(c & d) # 求交集,Counter({'a': 1, 'b': 1})
print(c | d) # 求并集,Counter({'c': 4, 'a': 3, 'b': 2})

双向队列(deque)

类似于list的容器,可以快速的在队列头部和尾部添加、删除元素

append(x)

将x添加到deque的右侧;
appendleft(x), 将x添加到deque的左侧;

clear()

将deque中的元素全部删除,最后长度为0;

count(x)

返回deque中元素等于x的个数;

extend(iterable)

将可迭代变量iterable中的元素添加至deque的右侧;
extendleft(iterable), 将变量iterable中的元素添加至deque的左侧,往左侧添加序列的顺序与可迭代变量iterable中的元素相反;

pop()

移除和返回deque中最右侧的元素,如果没有元素,将会报出IndexError;
popleft(), 移除和返回deque中最左侧的元素,如果没有元素,将会报出IndexError;

remove(value)

移除第一次出现的value,如果没有找到,报出ValueError;

reverse()

反转deque中的元素,并返回None;

rotate(n)

从右侧反转n步,如果n为负数,则从左侧反转,d.rotate(1)等于d.appendleft(d.pop());

maxlen

只读的属性,deque的最大长度,如果无解,就返回None;

除了以上的方法之外,deque还支持迭代、序列化、len(d)、reversed(d)、copy.copy(d)、copy.deepcopy(d),通过in操作符进行成员测试和下标索引,索引的时间复杂度是在两端是O(1),在中间是O(n),为了快速获取,可以使用list代替。

from collections import deque
d = deque('ghi')# 新建一个deque,有三个元素
for ele in d:# 遍历deque
    print(ele.upper())

d.append('j')# deque右侧添加一个元素
d.appendleft('f')# deque左侧添加一个元素
print(d)

d.pop()# 返回和移除最右侧元素
d.popleft() # 返回和移除最左侧元素
print(list(d))
print(d[0]) # 获取最左侧的元素
print(d[-1]) # 获取最右侧的元素

print(list(reversed(d)))# 以列表形式展示出倒序的deque的内容
print('h' in d) # 在deque中搜索
d.extend('jkl')# 一次添加多个元素
print(d)

d.rotate(1)# 往右侧翻转
print(d)
d.rotate(-1)# 往左侧翻转
print(d)

print(deque(reversed(d)))# 以逆序新建一个deque
d.clear()# 清空deque
d.pop()# 不能在空的deque上pop

d.extendleft('abc')# 以输入的逆序向左扩展
print(d)
输出:
G
H
I

deque(['f', 'g', 'h', 'i', 'j'])

['g', 'h', 'i']
g
i

['i', 'h', 'g']
True
deque(['g', 'h', 'i', 'j', 'k', 'l'])

deque(['l', 'g', 'h', 'i', 'j', 'k'])
deque(['g', 'h', 'i', 'j', 'k', 'l'])

deque(['l', 'k', 'j', 'i', 'h', 'g'])

Traceback (most recent call last):
  File "<input>", line 1, in <module>
IndexError: pop from an empty deque

deque(['c', 'b', 'a'])

默认字典(defaultdict)

dict的子类,可以调用提供默认值的函数,基本功能与dict一样,只是重写了一个方法missing(key)和增加了一个可写的对象变量default_factory。

missing(key)

  • 如果default_factory属性为None,就报出以key作为遍历的KeyError异常;
  • 如果default_factory不为None,就会向给定的key提供一个默认值,这个值插入到词典中,并返回;
  • 如果调用default_factory报出异常,这个异常在传播时不会改变;
  • 这个方法是当要求的key不存在时,dict类中的getitem()方法所调用,无论它返回或者报出什么,最终返回或报出给getitem();
  • 只有getitem()才能调用missing(),这意味着,如果get()起作用,如普通的词典,将会返回None作为默认值,而不是使用default_factory;

default_factory

这个属性用于missing()方法,使用构造器中的第一个参数初始化;

  • 使用list作为default_factory,很容易将一个key-value的序列转换为一个关于list的词典
from collections import *
s = [('yellow',1),('blue',2),('yellow',3),('blue',4),('red',5)]
d = defaultdict(list)
for k,v in s:
    d[k].append(v)
print(d.items())  # dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [5])])
  • 设置default_factory为int,使得defaultdict可以用于计数。当一个字母第一次遇到,默认从default_factory中调用int()用于提供一个默认为0的计数,递增操作会增加每个字母的计数。
from collections import *
s = 'gjgjhgftwy'
d = defaultdict(int)
for k in s:
    d[k] += 1
print(d.items())  # dict_items([('g', 3), ('j', 2), ('h', 1), ('f', 1), ('t', 1), ('w', 1), ('y', 1)])
  • 将default_factory设置为set,使得defaultdict可以建立一个关于set的词典
from collections import *
s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue',4)]
d = defaultdict(set)
for k,v in s:
    d[k].add(v)
print(d.items())  # dict_items([('red', {1, 3}), ('blue', {2, 4})])

有序字典(OrderedDict)

dict的子类,可以记住元素的添加顺序

  • class collections.OrderedDict,返回已给dict的子类,支持常规的dict的方法,OrderedDict是一个记住元素首次插入顺序的词典,如果一个元素重写已经存在的元素,那么原始的插入位置保持不变,如果删除一个元素再重新插入,那么它就在末尾。
  • OrderedDict.popitem(last=True),popitem方法返回和删除一个(key,value)对,如果last=True,就以LIFO方式执行,否则以FIFO方式执行。
  • OrderedDict也支持反向迭代,例如reversed()。

可命名元组(namedtuple)

可以创建包含名称的tuple,意味着代码可读性更强,namedtuple可以在任何常规元素使用的地方使用,而且它可以通过名称来获取字段信息而不仅仅是通过位置索引。

从tuple中继承

用namedtuple创建python风格的纸牌

给csv或者sqlite3返回的元组附上名称特别有用

namedtuple._make()

从已有的序列或者可迭代的对象中创建一个新的对象

from collections import *
from collections import *
Point = namedtuple('Point', ['x', 'y'])
t = [33,44]
print(Point._make(t))  # Point(x=33, y=44)

namedtuple._asdict()

返回一个OrderDict,由名称到对应值建立的映射

from collections import *
Point = namedtuple('Point', ['x', 'y'])

p = Point(x = 11,y = 22)
print(p)  # Point(x=11, y=22)
pDict = p._asdict()
print(pDict)  # OrderedDict([('x', 11), ('y', 22)])

namedtuple._replace()

返回一个新的namedtuple对象,用新值替换指定名称中的值

from collections import *
Point = namedtuple('Point', ['x', 'y'])

p = Point(x = 11,y = 22)
print(p)  # Point(x=11, y=22)
p2 = p._replace(x = 33)
print(p2)  

namedtuple._fields

以字符串构成的元组的形式返回namedtuple中的名称,在基于一个已经存在的namedtuple中创建新的namedtuple时,非常有用

from collections import *
Point = namedtuple('Point', ['x', 'y'])
print(Point._fields)  # ('x', 'y')
Color = namedtuple('Color',"red green blu")
Pixel = namedtuple('Pixel',Point._fields + Color._fields)
p = Pixel(11,22,128,255,0)
print(p)  # Pixel(x=11, y=22, red=128, green=255, blu=0)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值