Python的重要模块:collections (namedtuple、defaultdict、deque、Counter、OrderedDict、ChainMap)

collections 模块作用

包含双端队列 deque、默认字典 defaultdict、命名元组 namedtuple、计数器 CounterOrdereddictChainMap 等重要模块。他们是增强版的高级数据结构。

1. tuple 功能

为了讲解 namedtuple,所以先介绍 tuple 的功能,以便分析两者异同。
tuple 是一个不可变的元组,可迭代对象(内部实现了__iter__,或者__getitem__ 方法),可以进行拆包、tuple 的不可变性不是绝对的

user_tuple = ('sqz', 23, 'Master')
name, age, degree = user_tuple       # 这个过程称为拆包
name, *others = user_tuple           # 进阶版的拆包
print(name, others)
# Output: sqz, [23, 'Master']
name_tuple = ('sqz', ['xiaoming', 'liangliang'])
name_tuple[1].append('xiaozhang')  # 不可变性,不绝对
print(name_tuple)
# Output: ('sqz', ['xiaoming', 'liangliang', 'xiaozhang'])
tuple 和 list 相比的优势

immutable 的重要性:Python的性能优化tuple作为常量在编译时确定,加速脚本)、线程安全(线程无法对其进行修改)、可以作为 dictkey 值(可以进行哈希,而 list 不能)、 拆包特性。

2. namedtuple 功能

先来看简单的应用例子:

from collections import namedtuple

User = namedtuple('User', ['name', 'age', 'height', 'edu'])   # 这里面相当于创建了一个简单的类
user = User(name='sqz', age=23, height=175)
user.edu = 'master'                                           # 方便增加新的属性
print(user.name, user.age, user.height)   # Output: sqz 23 175

# 另一种赋值方式
user_tuple = ('sqz', 23, 175)
user = User(*user_tuple, 'master')
print(user.name, user.age, user.height, user.edu)   # Output: sqz 23 175 master

user_dict = {
"name":'sqz',
"age":23,
"height":175
}
user = User(**user_dict , edu = 'master')

# 使用内置函数_make()赋值,必须保持参数个数一致
user_dict = {
"name":'sqz',
"age":23,
"height":175
"edu" : "master"
}
user._make(user_dict)

# 使用内置函数_asdict()将namedtuple转化为一个OrderedDict
user_info_dict = user._asdict()

特点:

  1. 和创建一个简单类相比,形式更加简单,代码简洁。
  2. 节省空间,少了 class 中很多内置的函数和变量。
  3. 在对数据库进行操作时,如果需要给每一个条目增加属性,使用namedtuple作为数据结构,十分方便。
3. defaultdict 功能

defaultdict 是通过C语言实现的,性能特别的高。
defaultdict第一大作用:为新加入键值 key 分配默认的 value 值。实例如下:

from collections import defaultdict

default_dict = defaultdict(int)    # 默认 value值为 0
users = ['sqz1', 'sqz2', 'sqz3', 'sqz2', 'sqz3']    # 统计列表中数据出现的次数
for user in users:
    default_dict[user] += 1

defaultdict第二大作用:设计嵌套的字典结构,示例如下:

from collections import defaultdict

def gen_default():      # 可调用结构
    return {
        "name":""
        "nums":0
    }
default_dict = defaultdict(gen_default)  # 参数传入可调用结构
default_dict['group1']   # 嵌套字典,group1的 key值为'name','nums'
4. deque 功能

C语言实现,效率高。双端队列,使用可迭代对象初始化,如 list、tuple、dict。代码示例:

from collections import deque

user_deque = deque(['sqz1', 'sqz2', 'sqz3'])
user_deque.appendleft('sqz8')    # ['sqz8', 'sqz1', 'sqz2', 'sqz3'] 左侧添加数据
user_deque.clear()  # 清空数据

copy() 函数实现浅拷贝

from collections import deque

user_deque = deque(['sqz1', 'sqz2', ['sqz3']])
user_copy = user_deque.copy() # 不可变元素直接复制,可变元素直接指向(如 list)。
user_copy[0] = 'sqz100'
user_copy[2].append('sqzhaha')
print(user_deque)   # deque(['sqz1', 'sqz2', ['sqz3', 'sqzhaha']])
print(user_copy)  # deque(['sqz100', 'sqz2', ['sqz3', 'sqzhaha']])

Python 中同样提供了深拷贝的包:

import copy
from collections import deque

user_deque = deque(['sqz1', 'sqz2', ['sqz3']])
user_copy = copy.deepcopy(user_deque)  # 深拷贝
user_copy[2].append('sqzhaha')

print(user_deque)  # deque(['sqz1', 'sqz2', ['sqz3']])
print(user_copy)  # deque(['sqz1', 'sqz2', ['sqz3', 'sqzhaha']])

extend() 函数将两个 deque 合并为一个:

from collections import deque

user_deque = deque(['sqz1', 'sqz2', ['sqz3']])
user_deque1 = deque(['haha'])

user_deque.extend(user_deque1)  # 直接在 user_deque 上进行扩充,没有返回值

deque 是线程安全的,而 list 不是。

5. Counter

dict 的子类,用于统计元素数目,示例如下:

from collections import Counter

users = ['sqz1', 'sqz2', 'sqz4', 'sqz1', 'sqz2']
user_counter = Counter(users)
print(user_counter)  # Counter({'sqz1':2, 'sqz2':2, 'sqz4':1})  排序好的,次数最多的在前面

str_count = Counter('aanncddds')
str_count.update("bddc")  # 更新统计,增加统计数据

str_count.most_common(2)  # 取出前两个出现次数最多的元素
6. OrderedDict 功能

排好序的字典。继承自 dict,dict有的功能它都有。保持字典中元素的添加顺序。在Python3中,dict 和 OrderedDict 都是有序的。而在Python2下, dict 无序,而OrderedDict有序。

from collections import OrderedDict

user_dict = OrderedDict()
user_dict['b'] = 'sqz2'
user_dict['a'] = 'sqz3'
user_dict['c'] = 'sqz1'
print(user_dict)
# Output: {'b':'sqz2', 'a':'sqz3', 'c':'sqz1'}

OrderedDict 中一些重要函数:popitem()move_to_end()

print(user_dict.popitem())  # ('c', 'sqz1')
print(user_dict.pop())      # 会报错,pop() 函数中应传递 key值。

 print(user_dict.move_to_end('b'))  # 输出None
 print(user_dict)     # 输出:{'a':'sqz3', 'c':'sqz1', 'b':'sqz2'}    
7. ChainMap 功能

当想遍历多个可迭代对象时,将两个可迭代对象连接起来。在两个对象上加上迭代器,指向性的,并没有赋值结构和值。如下例:

from collections import ChainMap

user_dict1 = {'a':'sqz1', 'b':'sqz2'}
user_dict2 = {'c':'sqz2', 'd':'sqz3'}
new_dict = ChainMap(user_dict1, user_dict2)

for key, value in new_dict.items():
    print(key, value)
# Output:
# a sqz1
# b sqz2
# c sqz2
# d sqz3

当两个地点中有重复 key值时,只能访问出现第一次的键值对。
一些重要函数:new_child()、属性:maps

new_dict.new_child({'aa:'aa', 'bb':'bb'})  # add items
print(new_dict.maps) # [{'a':'sqz1', 'b':'sqz2'}, {'c':'sqz2', 'd':'sqz3'}, {'aa:'aa', 'bb':'bb'}] 以列表形式展现
new_dict.maps[0]['a'] = 'cherry'  # 直接修改原数据
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值