1. 什么是collections模块
Python是一种高级编程语言,专为代码可读性和简洁性而设计,具有广泛的标准库,包括math、datetime和os等模块。其中,collections模块在Python中具有特殊的地位,它提供了许多包括命名元组、有序字典、计数器和双端队列等高级数据类型的实现。同时,collections模块允许我们创建自己的高级数据结构,这有助于方便地组织和操作复杂的数据集合。
2. 命名元组
2.1 什么是命名元组
命名元组(namedtuple)是一个可命名的元组,它是一个简单而可扩展的数据类型。命名元组可以让我们拥有元组的不可变性和字典的可读性,开发者可以为单独的元组分配字段名,并像属性一样访问它们。命名元组在处理大量的元组时特别有用,其中每个元组都需要包含相同的信息。
为了理解namedtuple的概念,我们可以看一下如何使用普通元组:
tuple = ('Lucky', 25, 'Taiwan')
print(tuple[1])
#输出25
也就是说,当我们要访问元组中的元素时,我们必须指定其索引。如果使用一个又一个的元组,这是一个令人沮丧的过程。如果使用命名元组,我们可以使用属性来访问元组中的元素:
from collections import namedtuple
person = namedtuple('person', ['name', 'age', 'hometown'])
p = person('Lucky', 25, 'Taiwan')
print(p.age)
#输出25
这是一种声明性方式来创建一个简单的类,命名元组允许我们表达易于阅读和有意义的名字。
2.2 如何使用命名元组
我们可以使用命名元组轻松地构造一个可命名的元组:
from collections import namedtuple
person = namedtuple('person', ['name', 'age', 'hometown'])
p = person('Lucky', 25, 'Taiwan')
print(p)
#输出:person(name='Lucky', age=25, hometown='Taiwan')
在上面的示例中,我们首先通过from collections import namedtuple导入命名元组。 然后,我们使用namedtuple函数创建了一个新的命名元组类型person。 命名元组需要两个参数:类型名称和元素名称列表。 最后,我们使用命名元组创建了一个可命名的元组的实例p,将其附加到变量p中。
像字典一样使用命名元组:
print(p.name)
#输出:'Lucky'
print(p.age)
#输出:25
print(p.hometown)
#输出:'Taiwan'
这里,我们可以像访问字典的键一样访问命名元组的字段。
命名元组还支持许多普通元组的方法,例如索引和解包:
p = person('Lucky', 25, 'Taiwan')
name, age, hometown = p
print(name)
print(age)
print(hometown)
我们还可以使用_hasattr_方法确定特定命名元组是否具有特定属性:
print(hasattr(p, 'name'))
#输出:True
可以看出,命名元组在很多情况下都是一个很好的选择,它可以显著地简化代码。
3. 有序字典
3.1 什么是有序字典
有序字典(ordereddict)是Python之所以有这样一个库的原因之一,该字典允许对字典进行排序操作,每当我们针对该字典进行插入操作时,它将保持索引与键之间的顺序。
在Python 3.7中,字典的排序行为已更改以匹配该库,因此Python 3.7及更高版本的用户不必很担心字典的顺序问题。
3.2 如何使用有序字典
尽管字典本身字典键对的顺序不是有序的,但我们可以通过ordereddict类创建有序字典来保持它们的顺序:
from collections import OrderedDict
dictionary = OrderedDict()
dictionary['a'] = 1
dictionary['b'] = 2
dictionary['c'] = 3
print(dictionary.items())
#输出:odict_items([('a', 1), ('b', 2), ('c', 3)])
这里我们使用from collections import OrderedDict导入OrderedDict类。 我们创建了一个空OrderedDict对象dictionary,并逐个添加键值对。 在打印字典的键值对时,我们得到了一个有序的键值对列表。
我们还可以使用有序字典的其他方法来操作:
dictionary.move_to_end('a', last = False)
print(dictionary.items())
#输出:odict_items([('a', 1), ('c', 3), ('b', 2)])
move_to_end方法接受两个参数。第一个参数是要操作的键名称,第二个参数last是要将其移到哪一侧。在这种情况下,我们将“a”的值移动到字典的开头。
4. 计数器
4.1 什么是计数器
计数器(counter)是一个可以追踪值出现次数的容器。 它是Python内置字典的子类,其中每个键都映射到其相应的计数。
计数器非常适合计算在一个文档或集合中单词出现的次数,也就是词频统计问题。
4.2 如何使用计数器
计数器的使用很简单,只需要创建一个空的计数器,并使用下列代码逐个计数:
from collections import Counter
sentence = 'teaching assistant, assistant, teaching, teaching. '
words = sentence.split()
words_count = Counter(words)
print(words_count)
#输出:Counter({'teaching': 2, 'assistant': 2, 'teaching.': 1})
这里,我们首先使用from collections import Counter导入计数器。 我们使用字符串操作split()将字符串转换为单词,并将单词存储在一个名为words的列表中。 我们使用Counter函数统计单词出现的次数,并将其存储在words_count变量中。
作为计数器,它具有许多有用的方法,例如most_common(n)函数,用于获取以降序排序的前n个最常见元素的列表:
print(words_count.most_common(2))
#输出:[('teaching', 2), ('assistant', 2)]
5. 双端队列
5.1 什么是双端队列
双端队列(deque)是Python列表(subclass of list)的另一种形式,可从两个方向被操作。 双端队列被设计成用于对数据集合进行高效操作。 它可以用作队列,栈和下推堆栈等数据结构。
双端队列比列表更快。 比如,当您需要从两端删除/添加元素时,它比列表执行得更好,因为列表需要涉及对列表中间元素的复制。
5.2 如何使用双端队列
使用双端队列以从列表上浪费更少的时间插入和删除元素:
from collections import deque
num = deque([1, 2, 3, 4, 5])
num.append(6)
num.appendleft(0)
print(num)
#输出:deque([0, 1, 2, 3, 4, 5, 6])
这里,我们创建了一个双端队列对象num,将 1、2、3、4和5包含在内,并使用append()函数将6添加到列表的右侧并使用appendleft()函数将0添加到列表的左侧。
双端队列还支持其他有用的操作,例如删除左/右端元素、旋转和逆转它:
num.pop()
num.popleft()
num.rotate(1)
num.rotate(-1)
num.reverse()
这里,pop()和popleft()用于弹出队列中的元素,rotate()使队列中的元素向左或向右移动,reverse()使队列中的元素逆转。
总结
在本文中,我们了解了使用collections模块进行高级数据结构操作的重要性。我们学习了如何使用命名元组、有序字典、计数器和双端队列,并学习了如何使用这些高级数据类型的属性和方法。 熟练掌握Python中内置的这些高级数据类型可以帮助我们更好地组织和管理数据,并在学习Python预处理、数据清洗和统计处理等方面奠定了坚实的基础。