xml地图|网站地图|网站标签 [设为首页] [加入收藏]

智能家电

当前位置:美高梅游戏网站 > 智能家电 > Python连串之Collections内置模块(1),pythoncollect

Python连串之Collections内置模块(1),pythoncollect

来源:http://www.gd-chuangmei.com 作者:美高梅游戏网站 时间:2019-09-02 13:41

Python系列之Collections内置模块(1),pythoncollections

collections 是 python 的内置模块,源码位于 Lib/collections/__init__.py ,该模块提供了通用的数据容器。

deque 容器对象

通过 from collections import deque 引入,创建 deque 容器对象时,可通过设置参数为 Iterable 对象(如 tuple,list,str)或 maxlen=x(int类型) or None 进行初始化。

deque 容器支持线程安全,通过 append 或 pop 对 deque 的两端进行插入或移除元素时,时间复杂度为 O(1)。与 list 对象相比,list 同样有相同的 api 实现相同的功能,但是对于 pop(0) 或 insert(0, x) 等对 list 的操作,时间复杂度为 O(n)。

如果在初始化 deque 时未声明 maxlen 或声明 maxlen=None,那么 deque 容器可以容纳任意多的元素,否则, deque 容器会被定义为有限长度的元素容器。

一旦容器中的元素个数达到设置的 maxlen,当有新的元素加入时,则会在加入元素一端的另一端排除相同个数的元素,这样可以保证当前 deque 中的元素全部是最新加入的元素。

deque 对象函数

append(x)

appendleft(x)

clear()

copy()

count(x):返回容器中值为 x 的元素个数

extend(iterable)

extendleft(iterable)

index(x):在容器中查到第一个值为 x 的元素索引,如果不存在,抛起 ValueError 异常

insert(idx, x)

pop()

popleft()

remove(x)

reverse():翻转容器中的元素,并返回 None

rotate(n)

deque 对象只读属性

maxlen

除了上述的对象函数外,由于 deque 对象也是 Iterable 对象,那么 len(deque);reversed(deque);copy.copy(deque);copy.deepcopy(deque) 等函数同样起作用,同样 in 操作符也在遍历 deque 操作时使用,切片操作 deque[-1] 也可以返回容器中最后一个元素。如果对容器中的随机元素进行操作的话,建议使用 list。 

demo

获取文件中的 python 字符串所在的一行内容,和这行内容的前三行

 1 from collections import deque
 2 
 3 
 4 def search(lines, pattern, maxlen):
 5     pre_lines = deque(maxlen=maxlen)
 6     for line in lines:
 7         if pattern in line:
 8             yield line, pre_lines
 9         pre_lines.append(line)
10 
11 
12 if __name__ == '__main__':
13     with(open('./test.txt')) as f:
14         for line, pre_lines in search(f, 'python', 3):
15             for pre_line in pre_lines:
16                 print(pre_line, end='')
17             print(line)

 输入文本文件内容为

 1 c#
 2 c
 3 c++
 4 javascript
 5 python
 6 java
 7 delphi
 8 python
 9 golang
10 perl
11 css
12 html
13 python

 

通过代码输出为

c
c++
javascript
python

python
java
delphi
python

perl
css
html
python

 

collections 是 python 的内置模块,源码位于Lib/collections/__init__.py ,该模块提供了通用的数据...

Python系列之Collections内置模块(2),pythoncollections

defaultdict 返回一个类 dict 的对象,defaultdict 是内置的 dict 类的子类。

如果访问 dict 未初始化的 key 值时,会抛出 KeyError 异常。

1 s_tuple = ('a', 'b', 'a', 'a',
2            'c', 'a', 'b', 'a')
3 
4 c_dict = {}
5 
6 for s in s_tuple:
7     c_dict[s] += 1
8 
9 print(c_dict)

输出如下:

1 Traceback (most recent call last):
2   File "FileNamePath", line 7, in <module>
3     c_dict[s] += 1
4 KeyError: 'a'

对代码进行修正后如下:

 1 s_tuple = ('a', 'b', 'a', 'a',
 2            'c', 'a', 'b', 'a')
 3 
 4 c_dict = {}
 5 
 6 for s in s_tuple:
 7     if s not in c_dict:
 8         c_dict[s] = 1
 9     else:
10         c_dict[s] += 1
11 
12 print(c_dict)

能够正常输出每个 str 出现的统计次数,不过每次循环都要进行判断当前 dict 中是否存在这个 key 值。不过 dict 的 api 中提供了 setdefault() 方法,该方法需提供两个参数,第一个为 key 值,第二个为该 key 初始状态下的默认值。如果字典中不存在此 key 值,则该方法返回默认值,反之返回该 key 值对应的 value。

1 s_tuple = ('a', 'b', 'a', 'a',
2            'c', 'a', 'b', 'a')
3 
4 c_dict = {}
5 
6 for s in s_tuple:
7     c_dict[s] = c_dict.setdefault(s, 0) + 1
8 
9 print(c_dict)

下面引入 defaultdict 的用法,defaultdict 类初始化时接收一个类型作为参数,当访问的 key 值不存在时,可实例化传入的类型参数的实例作为默认值。

1 from collections import defaultdict
2 
3 d_defaultdict = defaultdict(list)
4 
5 print(d_defaultdict)
6 print(d_defaultdict.__getitem__('1'))
7 print(d_defaultdict)

输出如下:

1 defaultdict(<class 'list'>, {})
2 []
3 defaultdict(<class 'list'>, {'1': []})

由于初始化 defaultdict 时,传入的类型是 list,因此 key 为 '1' 的 value 默认为 [],如果参数为 tuple,那么 value 的默认值为 ()。

需要注意的是,默认值只有通过 defaultdict[key] 或 defaultdict.__getitem__(key) 访问 defaultdict 时才会被初始化。

extend

问题来了 defaultdict 是如何实现为不存在的 key 值初始化默认值的?

阅读 _collections.py 源码中的 class defaultdict(dict) 部分,可以看到一个 def __missing__(self, key) 的实例方法。

源码如下:

1 def __missing__(self, key):  # real signature unknown; restored from __doc__
2     """
3     __missing__(key) # Called by __getitem__ for missing key; pseudo-code:
4       if self.default_factory is None: raise KeyError((key,))
5       self[key] = value = self.default_factory()
6       return value
7     """
8     pass

由此可见,当通过 __getitem__ 方法访问 defaultdict 中的某个不存在的 key 值时,会在抛出的 KeyError 异常中进行处理,根据传入的类型参数返回初始化的 value 值。

那么,这个 __missing__ 方法中的内容可否自己实现呢,不妨试试:

 1 class defaultdict_copy(dict):
 2     def __missing__(self, key):
 3         self[key] = 'default'
 4         return 'default'
 5 
 6 
 7 d_defaultdict_copy = defaultdict_copy()
 8 print(d_defaultdict_copy)
 9 print(d_defaultdict_copy['1'])
10 print(d_defaultdict_copy)

输出如下:

1 {}
2 default
3 {'1': 'default'}

很明显,对于 dict 的继承类中,存在一个 __missing__ 的实例方法,可以通过重写该方法实现访问不存在的 key 值时进行 value 的初始化。

defaultdict 返回一个类 dict 的对象,defaultdict 是内置的 dict 类的子类。 如果访问 dict 未初始...

本文由美高梅游戏网站发布于智能家电,转载请注明出处:Python连串之Collections内置模块(1),pythoncollect

关键词: