Collections
'''This module implements specialized container datatypes providing
alternatives to Python's general purpose built-in containers, dict,
list, set, and tuple.
* namedtuple factory function for creating tuple subclasses with named fields
* deque list-like container with fast appends and pops on either end
* ChainMap dict-like class for creating a single view of multiple mappings
* Counter dict subclass for counting hashable objects
* OrderedDict dict subclass that remembers the order entries were added
* defaultdict dict subclass that calls a factory function to supply missing values
* UserDict wrapper around dictionary objects for easier dict subclassing
* UserList wrapper around list objects for easier list subclassing
* UserString wrapper around string objects for easier string subclassing
'''
OrderedDict:
OrderdDict是对字典类型的补充,实现有序字典。
dic = collections.OrderedDict()
dic["k1"] = "v1"
dic["k2"] = "v2"
dic["k3"] = "v3"
print(dic)
执行结果:无论执行多少次结果一样 OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')]
实现原理:相当于用列表(有序)来维护字典(无序)排序,以下仅供理解
# dic = {"k1":"v1","k2":"v2"}
# li = ["k1","k2"]
# for i in li:
# print(dic.get(i))
defaultDict:
使用dict
时,如果引用的Key不存在,就会抛出KeyError
。如果希望key不存在时,返回一个默认值,就可以用defaultdict
:
stats = defaultdict(int)
stats["counter"] += 1
优化代码:
原始dict
"""
将大于55的值保存在字典的一个Key中,
将小于55的值保存在字典的另一个key中。
"""
lists = [11, 22, 33, 44, 55, 66, 77, 88, 99]
dicts = {}
for i in lists:
if i > 55:
if "k1" in dicts.keys():
dicts["k1"].append(i)
else:
dicts["k1"] = [i,]
else:
if "k2" in dicts.keys():
dicts["k2"].append(i)
else:
dicts["k2"] = [i,]
print(dicts)
>>>
{'k2': [11, 22, 33, 44, 55], 'k1': [66, 77, 88, 99]}
defaultdict
"""
将大于55的值保存在字典的一个Key中,
将小于55的值保存在字典的另一个key中。
"""
lists = [11, 22, 33, 44, 55, 66, 77, 88, 99]
dicts = defaultdict(list)
for i in lists:
if i > 55:
dicts["k1"].append(i)
else:
dicts["k2"].append(i)
print(dicts)
>>>
defaultdict(<class 'list'>, {'k2': [11, 22, 33, 44, 55], 'k1': [66, 77, 88, 99]})
nametuple:
有名元组: 相比tuple,dictionary,namedtuple略微有点综合体的意味:直观、使用方便,墙裂建议大家在合适的时候多用用namedtuple。
namedtuple能够用来创建类似于元祖的数据类型,除了能够用索引来访问数据,能够迭代,更能够方便的通过属性名来访问数据。
在python中,传统的tuple类似于数组,只能通过下标来访问各个元素,我们还需要注释每个下标代表什么数据。通过使用namedtuple,每个元素有了自己的名字,类似于C语言中的struct,这样数据的意义就可以一目了然了。
# 定义一个namedtuple类型User,并包含name,sex和age属性。
User = namedtuple('User', ['name', 'sex', 'age'])
# 创建一个User对象
user = User(name='kongxx', sex='male', age=21)
# 也可以通过一个list来创建一个User对象,这里注意需要使用"_make"方法
user2 = User._make(['kongxx', 'male', 21])
print(user, user2)
>>>
User(name='user1', sex='male', age=21)
# 获取用户的属性
print(user.name)
print(user.sex)
print(user.age)
# 修改对象属性,注意要使用"_replace"方法
user = user._replace(age=22)
print(user)
>>>
User(name='user1', sex='male', age=21)
# 将User对象转换成字典,注意要使用"_asdict"
print(user._asdict())
>>>
OrderedDict([('name', 'kongxx'), ('sex', 'male'), ('age', 22)])
deque
使用list
存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list
是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
q = deque([1, 2, 3])
q.append(4)
q.appendleft(0)
print(q)
>>>
deque([0, 1, 2, 3, 4])
q.pop()
q.popleft()
print(q)
>>>
deque([1, 2, 3])
Counter
Counter
是一个简单的计数器,例如统计字符出现的个数:
c = Counter(["a", "a", "a", "b", "b", "b"])
print(c)
c2 = Counter([x for x in "programming"])
print(c2)
c3 = Counter("programming")
print(c3)
>>>运行结果
Counter({'b': 3, 'a': 3})
Counter({'g': 2, 'm': 2, 'r': 2, 'i': 1, 'p': 1, 'a': 1, 'o': 1, 'n': 1})
Counter({'g': 2, 'm': 2, 'r': 2, 'i': 1, 'p': 1, 'a': 1, 'o': 1, 'n': 1})
未完待续。。。