Hero Circle Shape
Hero Moon Shape
Hero Right Shape
苹果怎么下载tokenpocket钱包|collections python

苹果怎么下载tokenpocket钱包|collections python

  • 作者: 苹果怎么下载tokenpocket钱包
  • 2024-03-08 21:37:13

【万字长文详解】Python库collections,让你击败99%的Pythoner - 知乎

【万字长文详解】Python库collections,让你击败99%的Pythoner - 知乎首发于Python基础方法详解切换模式写文章登录/注册【万字长文详解】Python库collections,让你击败99%的Pythoner小伍哥聊风控风控算法、风控策略,反欺诈,异常检测,复杂网络挖掘、风控转行Python的集合(collections)模块,为很多用其他方法很难实现的场景提供了解决方案。本文我们将会学习该模块的抽象概念是如何产生的,日后处理不同问题的过程中迟早会用得到这些知识。免责声明:这篇文章是关于Python的一个相当高级的特性,如果你刚入门,建议先收藏,请等一等再学!没想到这篇文章这么受欢迎, 修改优化下。 一、模块概述1、模块作用官方说法:collections模块实现了特定目标的容器,以提供Python标准内建容器dict ,list , set , 和tuple的替代选择。 通俗说法:Python内置的数据类型和方法,collections模块在这些内置类型的基础提供了额外的高性能数据类型,比如基础的字典是不支持顺序的,collections模块的OrderedDict类构建的字典可以支持顺序,collections模块的这些扩展的类用处非常大,熟练掌握该模块,可以大大简化Python代码,提高Python代码逼格和效率,高手入门必备。2、模块资料关于该模块,官方的参考资料写的非常详细,也很有价值,大家可以参考中文文档:https://docs.python.org/zh-cn/3/library/collections.html#module-collections英文文档:https://docs.python.org/3/library/collections.html#module-collections3、模块子类用collections.__all__查看所有的子类,一共包含9个import collections

print(collections.__all__)

['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',

'UserString', 'Counter', 'OrderedDict', 'ChainMap']这个模块实现了特定目标的容器,以提供Python标准内建容器dict , list , set , 和tuple 的替代选择。namedtuple()创建命名元组子类的工厂函数,生成可以使用名字来访问元素内容的tuple子类deque类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)ChainMap类似字典(dict)的容器类,将多个映射集合到一个视图里面Counter字典的子类,提供了可哈希对象的计数功能OrderedDict字典的子类,保存了他们被添加的顺序,有序字典defaultdict字典的子类,提供了一个工厂函数,为字典查询提供一个默认值UserDict封装了字典对象,简化了字典子类化UserList封装了列表对象,简化了列表子类化UserString封装了字符串对象,简化了字符串子类化(中文版翻译有误) 二、计数器-Counter1、基础介绍一个计数器工具提供快速和方便的计数,Counter是一个dict的子类,用于计数可哈希对象。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数,Counter类有点像其他语言中的bags或multisets。简单说,就是可以统计计数,来几个例子看看就清楚了,比如#计算top10的单词

from collections import Counter

import re

text = 'remove an existing key one level down remove an existing key one level down'

words = re.findall(r'\w+', text)

Counter(words).most_common(10)

[('remove', 2),('an', 2),('existing', 2),('key', 2),('one', 2)('level', 2),('down', 2)]

#计算列表中单词的个数

cnt = Counter()

for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:

cnt[word] += 1

cnt

Counter({'red': 2, 'blue': 3, 'green': 1})

#上述这样计算有点嘛,下面的方法更简单,直接计算就行

L = ['red', 'blue', 'red', 'green', 'blue', 'blue']

Counter(L)

Counter({'red': 2, 'blue': 3, 'green': 1}元素从一个iterable 被计数或从其他的mapping (or counter)初始化:from collections import Counter

#字符串计数

Counter('gallahad')

Counter({'g': 1, 'a': 3, 'l': 2, 'h': 1, 'd': 1})

#字典计数

Counter({'red': 4, 'blue': 2})

Counter({'red': 4, 'blue': 2})

#是个啥玩意计数

Counter(cats=4, dogs=8)

Counter({'cats': 4, 'dogs': 8})

Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])

Counter({'red': 2, 'blue': 3, 'green': 1})计数器对象除了字典方法以外,还提供了三个其他的方法:1、elements()描述:返回一个迭代器,其中每个元素将重复出现计数值所指定次。 元素会按首次出现的顺序返回。 如果一个元素的计数值小于1,elements() 将会忽略它。语法:elements( )参数:无c = Counter(a=4, b=2, c=0, d=-2)

list(c.elements())

['a', 'a', 'a', 'a', 'b', 'b']

sorted(c.elements())

['a', 'a', 'a', 'a', 'b', 'b']

c = Counter(a=4, b=2, c=0, d=5)

list(c.elements())

['a', 'a', 'a', 'a', 'b', 'b', 'd', 'd', 'd', 'd', 'd']2、most_common()返回一个列表,其中包含n个最常见的元素及出现次数,按常见程度由高到低排序。 如果 n 被省略或为None,most_common() 将返回计数器中的所有元素,计数值相等的元素按首次出现的顺序排序,经常用来计算top词频的词语。Counter('abracadabra').most_common(3)

[('a', 5), ('b', 2), ('r', 2)]

Counter('abracadabra').most_common(5)

[('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]3、subtract()从迭代对象或映射对象减去元素。像dict.update() 但是是减去,而不是替换。输入和输出都可以是0或者负数。c = Counter(a=4, b=2, c=0, d=-2)

d = Counter(a=1, b=2, c=3, d=4)

c.subtract(d)

c

Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

#减去一个abcd

str0 = Counter('aabbccdde')

str0

Counter({'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 1})

str0.subtract('abcd')

str0

Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1}4、字典方法通常字典方法都可用于Counter对象,除了有两个方法工作方式与字典并不相同。fromkeys(iterable)这个类方法没有在Counter中实现。update([iterable-or-mapping])从迭代对象计数元素或者从另一个映射对象 (或计数器) 添加。 像 dict.update() 但是是加上,而不是替换。另外,迭代对象应该是序列元素,而不是一个 (key, value) 对。sum(c.values()) # total of all counts

c.clear() # reset all counts

list(c) # list unique elements

set(c) # convert to a set

dict(c) # convert to a regular dictionary

c.items() # convert to a list of (elem, cnt) pairs

Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs

c.most_common()[:-n-1:-1] # n least common elements

+c # remove zero and negative counts5、数学操作这个功能非常强大,提供了几个数学操作,可以结合 Counter 对象,以生产 multisets (计数器中大于0的元素)。 加和减,结合计数器,通过加上或者减去元素的相应计数。交集和并集返回相应计数的最小或最大值。每种操作都可以接受带符号的计数,但是输出会忽略掉结果为零或者小于零的计数。c = Counter(a=3, b=1)

d = Counter(a=1, b=2)

c + d # add two counters together: c[x] + d[x]

Counter({'a': 4, 'b': 3})

c - d # subtract (keeping only positive counts)

Counter({'a': 2})

c & d # intersection: min(c[x], d[x])

Counter({'a': 1, 'b': 1})

c | d # union: max(c[x], d[x])

Counter({'a': 3, 'b': 2})单目加和减(一元操作符)意思是从空计数器加或者减去。c = Counter(a=2, b=-4)

+c

Counter({'a': 2})

-c

Counter({'b': 4})写一个计算文本相似的算法,加权相似def str_sim(str_0,str_1,topn):

topn = int(topn)

collect0 = Counter(dict(Counter(str_0).most_common(topn)))

collect1 = Counter(dict(Counter(str_1).most_common(topn)))

jiao = collect0 & collect1

bing = collect0 | collect1

sim = float(sum(jiao.values()))/float(sum(bing.values()))

return(sim)

str_0 = '定位手机定位汽车定位GPS定位人定位位置查询'

str_1 = '导航定位手机定位汽车定位GPS定位人定位位置查询'

str_sim(str_0,str_1,5)

0.75 二、双向队列-deque双端队列,可以快速的从另外一侧追加和推出对象,deque是一个双向链表,针对list连续的数据结构插入和删除进行优化。它提供了两端都可以操作的序列,这表示在序列的前后你都可以执行添加或删除操作。双向队列(deque)对象支持以下方法:1、append()添加 x 到右端。d = deque('ghi')

d.append('j')

d

deque(['g', 'h', 'i', 'j'])2、appendleft()添加 x 到左端。d.appendleft('f')

d

deque(['f', 'g', 'h', 'i', 'j'])3、clear()移除所有元素,使其长度为0.d = deque('ghi')

d.clear()

d

deque([])4、copy()创建一份浅拷贝。d = deque('xiaoweuge')

y = d.copy()

print(y)

deque(['x', 'i', 'a', 'o', 'w', 'e', 'u', 'g', 'e'])5、count()计算 deque 中元素等于 x 的个数。d = deque('xiaoweuge-shuai')

d.count('a')

26、extend()扩展deque的右侧,通过添加iterable参数中的元素。a = deque('abc')

b = deque('cd')

a.extend(b)

a

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

#与append 的区别

a = deque('abc')

b = deque('cd')

a.append(b)

deque(['a', 'b', 'c', deque(['c', 'd'])])7、extendleft()扩展deque的左侧,通过添加iterable参数中的元素。注意,左添加时,在结果中iterable参数中的顺序将被反过来添加。a = deque('abc')

b = deque('cd')

a.extendleft(b)

a

deque(['d', 'c', 'a', 'b', 'c'])8、index()返回 x 在 deque 中的位置(在索引 start 之后,索引 stop 之前)。 返回第一个匹配项,如果未找到则引发 ValueError。d = deque('xiaoweuge')

d.index('w')

49、insert()在位置 i 插入 x 。如果插入会导致一个限长 deque 超出长度 maxlen 的话,就引发一个 IndexError。a = deque('abc')

a.insert(1,'X')

deque(['a', 'X', 'b', 'c'])10、pop()移去并且返回一个元素,deque 最右侧的那一个。 如果没有元素的话,就引发一个 IndexError。d.pop()

'j'11、popleft()移去并且返回一个元素,deque 最左侧的那一个。 如果没有元素的话,就引发 IndexError。d.popleft()

'f'12、remove(value)移除找到的第一个 value。 如果没有的话就引发 ValueError。a = deque('abca')

a.remove('a')

a

deque(['b', 'c', 'a'])13、reverse()将deque逆序排列。返回 None 。#逆序排列

d = deque('ghi') # 创建一个deque

list(reversed(d))

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

deque(reversed(d))

deque(['i', 'h', 'g'])14、rotate(n=1)向右循环移动 n 步。 如果 n 是负数,就向左循环。如果deque不是空的,向右循环移动一步就等价于 d.appendleft(d.pop()) , 向左循环一步就等价于 d.append(d.popleft()) 。# 向右边挤一挤

d = deque('ghijkl')

d.rotate(1)

d

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

# 向左边挤一挤

d.rotate(-1)

d

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

#看一个更明显的

x = deque('12345')

x

deque(['1', '2', '3', '4', '5'])

x.rotate()

x

deque(['5', '1', '2', '3', '4'])

d = deque(['12','av','cd'])

d.rotate(1)

deque(['cd', '12', 'av'15、maxlenDeque的最大尺寸,如果没有限定的话就是 None 。from collections import deque

d=deque(maxlen=10)

for i in range(20):

d.append(i)

d

deque([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])除了以上操作,deque还支持迭代、封存、len(d)、reversed(d)、copy.deepcopy(d)、copy.copy(d)、成员检测运算符 in 以及下标引用例如通过 d[0] 访问首个元素等。 索引访问在两端的复杂度均为 O(1) 但在中间则会低至 O(n)。 如需快速随机访问,请改用列表。Deque从版本3.5开始支持 __add__(), __mul__(), 和 __imul__() 。 from collections import deque

d = deque('ghi') # 创建一个deque

for elem in d:

print(elem.upper())

G

H

I

#从右边添加一个元素

d.append('j')

d

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

#从左边添加一个元素

d.appendleft('f')

d

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

#右边删除

d.pop()

'j'

#左边边删除

d.popleft()

'f'

#看看还剩下啥

list(d) #

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

#成员检测

'h' in d

True

#添加多个元素

d.extend('jkl')

d

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

d.clear() # empty the deque

d.pop() # cannot pop from an empty deque

Traceback (most recent call last):

File "", line 1, in -toplevel-

d.pop()

IndexError: pop from an empty deque

d.extendleft('abc') # extendleft() reverses the input order

d

deque(['c', 'b', 三、有序字典-OrderedDict 有序词典就像常规词典一样,但有一些与排序操作相关的额外功能,popitem() 方法有不同的签名。它接受一个可选参数来指定弹出哪个元素。move_to_end() 方法,可以有效地将元素移动到任一端。有序词典就像常规词典一样,但有一些与排序操作相关的额外功能。由于内置的 dict 类获得了记住插入顺序的能力(在 Python 3.7 中保证了这种新行为),它们变得不那么重要了。一些与 dict 的不同仍然存在:常规的 dict 被设计为非常擅长映射操作。 跟踪插入顺序是次要的。OrderedDict 旨在擅长重新排序操作。 空间效率、迭代速度和更新操作的性能是次要的。算法上, OrderedDict 可以比 dict 更好地处理频繁的重新排序操作。 这使其适用于跟踪最近的访问(例如在 LRU cache 中)。对于 OrderedDict ,相等操作检查匹配顺序。OrderedDict 类的 popitem() 方法有不同的签名。它接受一个可选参数来指定弹出哪个元素。OrderedDict 类有一个 move_to_end() 方法,可以有效地将元素移动到任一端。Python 3.8之前, dict 缺少 __reversed__() 方法。传统字典方法OrderedDict方法差异clearclearcopycopyfromkeysfromkeysgetgetitemsitemskeyskeyspoppoppopitempopitemOrderedDict 类的 popitem() 方法有不同的签名。它接受一个可选参数来指定弹出哪个元素。setdefaultsetdefaultupdateupdatevaluesvaluesmove_to_end可以有效地将元素移动到任一端。1、popitem语法:popitem(last=True) 功能:有序字典的 popitem() 方法移除并返回一个 (key, value) 键值对。 如果 last 值为真,则按 LIFO 后进先出的顺序返回键值对,否则就按 FIFO 先进先出的顺序返回键值对。from collections import OrderedDict

d = OrderedDict.fromkeys('abcde')

d.popitem()

('e', None)

d

OrderedDict([('a', None), ('b', None), ('c', None), ('d', None)])

#last=False时,弹出第一个

d = OrderedDict.fromkeys('abcde')

''.join(d.keys())

'abcde'

d.popitem(last=False)

''.join(d.keys())

'bcde'2、move_to_endfrom collections import OrderedDict

d = OrderedDict.fromkeys('abcde')

d.move_to_end('b')

''.join(d.keys())

'acdeb'

d

OrderedDict([('a', None), ('c', None), ('d', None), ('e', None), ('b', None)])

d.move_to_end('b', last=False)

''.join(d.keys())

'bacde'3、reversed()相对于通常的映射方法,有序字典还另外提供了逆序迭代的支持,通过reversed() 。 d = OrderedDict.fromkeys('abcde')

list(reversed(d))

['e', 'd', 'c', 'b', 'a']四、可命名元组-namedtuple生成可以使用名字来访问元素内容的tuple子类,命名元组赋予每个位置一个含义,提供可读性和自文档性。它们可以用于任何普通元组,并添加了通过名字获取值的能力,通过索引值也是可以的。1、参数介绍namedtuple(typename,field_names,*,verbose=False, rename=False, module=None)1)typename:该参数指定所创建的tuple子类的类名,相当于用户定义了一个新类。2)field_names:该参数是一个字符串序列,如 ['x','y']。此外,field_names 也可直接使用单个字符串代表所有字段名,多个字段名用空格、逗号隔开,如 'x y' 或 'x,y'。任何有效的 Python 标识符都可作为字段名(不能以下画线开头)。有效的标识符可由字母、数字、下画线组成,但不能以数字、下面线开头,也不能是关键字(如 return、global、pass、raise 等)。3)rename:如果将该参数设为 True,那么无效的字段名将会被自动替换为位置名。例如指定 ['abc','def','ghi','abc'],它将会被替换为 ['abc', '_1','ghi','_3'],这是因为 def 字段名是关键字,而 abc 字段名重复了。4)verbose:如果该参数被设为 True,那么当该子类被创建后,该类定义就被立即打印出来。5)module:如果设置了该参数,那么该类将位于该模块下,因此该自定义类的 __module__ 属性将被设为该参数值。2、应用案例1)水族箱案例Python元组是一个不可变的,或不可改变的,有序的元素序列。元组经常用来表示纵列数据;例如,一个CSV文件中的行数或一个SQL数据库中的行数。一个水族箱可以用一系列元组来记录它的鱼类的库存。一个单独的鱼类元组:这个元组由三个字符串元素组成。虽然在某些方面很有用,但是这个元组并没有清楚地指明它的每个字段代表什么。实际上,元素0是一个名称,元素1是一个物种,元素2是一个饲养箱。鱼类元组字段说明:这个表清楚地表明,该元组的三个元素都有明确的含义。来自collections模块的namedtuple允许你向一个元组的每个元素添加显式名称,以便在你的Python程序中明确这些元素的含义。让我们使用namedtuple来生成一个类,从而明确地命名鱼类元组的每个元素:from collections import namedtuple 可以让你的Python程序访问namedtuple工厂函数。namedtuple()函数调用会返回一个绑定到名称Fish的类。namedtuple()函数有两个参数:我们的新类“Fish”的期望名称和命名元素["name"、"species”、“tank"]的一个列表。我们可以使用Fish类来表示前面的鱼类元组:如果我们运行这段代码,我们将看到以下输出:sammy是使用Fish类进行实例化的。sammy是一个具有三个明确命名元素的元组。sammy的字段可以通过它们的名称或者一个传统的元组索引来访问:如果我们运行这两个print调用,我们将看到以下输出:访问.species会返回与使用[1]访问sammy的第二个元素相同的值。使用collections模块中的namedtuple可以在维护元组(即它们是不可变的、有序的)的重要属性的同时使你的程序更具可读性。此外,namedtuple工厂函数还会向Fish实例添加几个额外的方法。使用._asdict()将一个实例转换为字典:如果我们运行print,你会看到如下输出:在sammy上调用.asdict()将返回一个字典,该字典会将三个字段名称分别映射到它们对应的值。大于3.8的Python版本输出这一行的方式可能略有不同。例如,你可能会看到一个OrderedDict,而不是这里显示的普通字典。2)加法器案例from collections import namedtuple

# 定义命名元组类:Point

Point = namedtuple('Point', ['x', 'y'])

# 初始化Point对象,即可用位置参数,也可用命名参数

p = Point(11, y=22)

# 像普通元组一样用根据索引访问元素

print(p[0] + p[1])

33

#执行元组解包,按元素的位置解包

a, b = p

print(a, b)

11, 22

#根据字段名访问各元素

print(p.x + p.y)

33

print(p)

Point(x=11, y=22)3、三个方法备注: 在Python中,带有前导下划线的方法通常被认为是“私有的”。但是,namedtuple提供的其他方法(如._asdict()、._make()、._replace()等)是公开的。除了继承元组的方法,命名元组还支持三个额外的方法和两个属性。为了防止字段名冲突,方法和属性以下划线开始。_make(iterable)类方法从存在的序列或迭代实例创建一个新实例。t = [14, 55]

Point._make(t)_asdict()返回一个新的 dict ,它将字段名称映射到它们对应的值:p = Point(x=11, y=22)

p._asdict()

OrderedDict([('x', 11), ('y', 22)])_replace(**kwargs)返回一个新的命名元组实例,并将指定域替换为新的值p = Point(x=11, y=22)

p._replace(x=33)

Point(x=33, y=22)4、两个属性_fields字符串元组列出了字段名。用于提醒和从现有元组创建一个新的命名元组类型。p._fields # view the field names

('x', 'y')

Color = namedtuple('Color', 'red green blue')

Pixel = namedtuple('Pixel', Point._fields + Color._fields)

Pixel(11, 22, 128, 255, 0)

Pixel(x=11, y=22, red=128, green=255, blue=0)_field_defaults字典将字段名称映射到默认值。Account = namedtuple('Account', ['type', 'balance'], defaults=[0])

Account._field_defaults

{'balance': 0}

Account('premium')

Account(type='premium', balance=0)5、其他函数getattr()要获取这个名字域的值,使用 getattr() 函数 : getattr(p, 'x')

11转换一个字典到命名元组,使用 ** 两星操作符d = {'x': 11, 'y': 22}

Point(**d)

Point(x=11, y=22)因为一个命名元组是一个正常的Python类,它可以很容易的通过子类更改功能。这里是如何添加一个计算域和定宽输出打印格式:class Point(namedtuple('Point', ['x', 'y'])):

__slots__ = ()

@property

def hypot(self):

return (self.x ** 2 + self.y ** 2) ** 0.5

def __str__(self):

return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)

for p in Point(3, 4), Point(14, 5/7):

print(p)

Point: x= 3.000 y= 4.000 hypot= 5.000

Point: x=14.000 y= 0.714 hypot=14.018五、默认字典-defaultdict在Python字典中收集数据通常是很有用的。在字典中获取一个 key 有两种方法, 第一种 get , 第二种 通过 [] 获取.使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict。当我使用普通的字典时,用法一般是dict={},添加元素的只需要dict[element] =value即,调用的时候也是如此,dict[element] = xxx,但前提是element字典里,如果不在字典里就会报错这时defaultdict就能排上用场了,defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值,这个默认值是什么呢,下面会说1、基础介绍defaultdict([default_factory[, ...]])返回一个新的类似字典的对象。 defaultdict是内置dict类的子类。它重载了一个方法并添加了一个可写的实例变量。其余的功能与dict类相同,此处不再重复说明。本对象包含一个名为default_factory的属性,构造时,第一个参数用于为该属性提供初始值,默认为 None。所有其他参数(包括关键字参数)都相当于传递给 dict 的构造函数。defaultdict 对象除了支持标准 dict 的操作,还支持以下方法作为扩展:__missing__(key)如果 default_factory 属性为 None,则调用本方法会抛出 KeyError 异常,附带参数 key。如果 default_factory 不为 None,则它会被(不带参数地)调用来为 key 提供一个默认值,这个值和 key 作为一对键值对被插入到字典中,并作为本方法的返回值返回。如果调用 default_factory 时抛出了异常,这个异常会原封不动地向外层传递。在无法找到所需键值时,本方法会被 dict 中的 __getitem__() 方法调用。无论本方法返回了值还是抛出了异常,都会被 __getitem__() 传递。注意,__missing__() 不会 被 __getitem__() 以外的其他方法调用。意味着 get() 会像正常的 dict 那样返回 None,而不是使用 default_factory。2、示例介绍使用 list 作为 default_factory,很轻松地将(键-值对组成的)序列转换为(键-列表组成的)字典 s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

d = defaultdict(list)

for k, v in s:

d[k].append(v)

sorted(d.items())

[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]当每个键第一次遇见时,它还没有在字典里面,所以自动创建该条目,即调用default_factory方法,返回一个空的 list。 list.append() 操作添加值到这个新的列表里。当再次存取该键时,就正常操作,list.append() 添加另一个值到列表中。这个计数比它的等价方法dict.setdefault()要快速和简单: s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

d = {}

for k, v in s:

d.setdefault(k, []).append(v)

sorted(d.items())

[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]设置 default_factory为int,使defaultdict用于计数(类似其他语言中的 bag或multiset): s = 'mississippi'

d = defaultdict(int)

for k in s:

d[k] += 1

sorted(d.items())

[('i', 4), ('m', 1), ('p', 2), ('s', 4)]设置 default_factory 为 set 使 defaultdict 用于构建 set 集合: 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)

sorted(d.items())

[('blue', {2, 4}), ('red', {1, 3})]defaultdict绝不会引发一个KeyError。如果一个键不存在,defaultdict会插入并返回一个占位符值来代替:如果我们运行这段代码,我们将看到如下输出:defaultdict会插入并返回一个占位符值,而不是引发一个KeyError。在本例中,我们将占位符值指定为一个列表。相比之下,常规字典会在缺失的键上引发一个KeyError:如果我们运行这段代码,我们将看到如下输出:当我们试图访问一个不存在的键时,常规字典my_regular_dict会引发一个KeyError。defaultdict的行为与常规字典不同。defaultdict会不带任何参数调用占位符值来创建一个新对象,而不是在缺失的键上引发一个KeyError。在本例中,是调用list()创建一个空列表。继续我们虚构的水族箱示例,假设我们有一个表示水族箱清单的鱼类元组列表:水族箱中有三种鱼——它们的名字、种类和饲养箱在这三个元组中都有指出。我们的目标是按饲养箱组织我们的清单—我们想知道每个饲养箱中存在的鱼的列表。换句话说,我们需要一个能将“tank-a”映射到["Jamie", "Mary"] ,并且将“tank-b”映射到["Jamie"]的字典。我们可以使用defaultdict来按饲养箱对鱼进行分组:运行这段代码,我们将看到以下输出:fish_names_by_tank被声明为一个defaultdict,它默认会插入list()而不是引发一个KeyError。由于这保证了fish_names_by_tank中的每个键都将指向一个list,所以我们可以自由地调用.append()来将名称添加到每个饲养箱的列表中。这里,defaultdict帮助你减少了出现未预期的KeyErrors的机会。减少未预期的KeyErrors意味着你可以用更少的行更清晰地编写你的程序。更具体地说,defaultdict习惯用法让你避免了手动地为每个饲养箱实例化一个空列表。如果没有 defaultdict, for循环体可能看起来更像这样:使用常规字典(而不是defaultdict)意味着for循环体总是必须检查fish_names_by_tank中给定的tank是否存在。只有在验证了fish_names_by_tank中已经存在tank,或者已经使用一个[]初始化了tank之后,我们才可以添加鱼类名称。在填充字典时,defaultdict可以帮助我们减少样板代码,因为它从不引发KeyError。六、映射链-ChainMap 1、ChainMap是什么ChainMap最基本的使用,可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询。ChainMap:将多个字典视为一个,解锁Python超能力。ChainMap是由Python标准库提供的一种数据结构,允许你将多个字典视为一个。换句话说:ChainMap是一个基于多dict的可更新的视图,它的行为就像一个普通的dict。ChainMap类用于快速链接多个映射,以便将它们视为一个单元。它通常比创建新字典和多次调用update()快得多。你以前可能从来没有听说过ChainMap,你可能会认为ChainMap的使用情况是非常特定的。坦率地说,你是对的。我知道的用例包括:通过多个字典搜索提供链缺省值经常计算字典子集的性能关键的应用程序2、特性1)找到一个就不找了:这个列表是按照第一次搜索到最后一次搜索的顺序组织的,搜索查询底层映射,直到一个键被找到。2)更新原始映射:不同的是,写,更新和删除只操作第一个映射。3)支持所有常用字典方法。简而言之ChainMap:将多个字典视为一个,解锁Python超能力。Python标准库中的集合模块包含许多为性能而设计的实用的数据结构。著名的包括命名元组或计数器。今天,通过实例,我们来看看鲜为人知的ChainMap。通过浏览具体的示例,我希望给你一个提示,关于在更高级的Python工作中使用ChainMap将如何从中受益。3、应用案例-基础案例from collections import ChainMap

baseline = {'music': 'bach', 'art': 'rembrandt'}

adjustments = {'art': 'van gogh', 'opera': 'carmen'}

ChainMap(adjustments, baseline)

ChainMap({'art': 'van gogh', 'opera': 'carmen'}, {'music': 'bach', 'art': 'rembrandt'})

list(ChainMap(adjustments, baseline))

['music', 'art', 'opera']

#存在重复元素时,也不会去重

dcic1 = {'label1': '11', 'label2': '22'}

dcic2 = {'label2': '22', 'label3': '33'}

dcic3 = {'label4': '44', 'label5': '55'}

last = ChainMap(dcic1, dcic2,dcic3)

last

ChainMap({'label1': '11', 'label2': '22'}, {'label2': '22', 'label3': '33'}, {'label4': '44', 'label5': '55'})new_child()方法用法:new_child(m=None) 返回一个新的ChainMap类,包含了一个新映射(map),后面跟随当前实例的全部映射map。如果m被指定,它就成为不同新的实例,就是在所有映射前加上 m,如果没有指定,就加上一个空字典,这样的话一个 d.new_child() 调用等价于ChainMap({}, *d.maps) 。这个方法用于创建子上下文,不改变任何父映射的值。last.new_child(m={'key_new':888})

ChainMap({'key_new': 888}, {'label1': '11', 'label2': '22'}, {'label2': '22', 'label3': '33'},

{'label4': '44', 'label5': '55'})parents属性属性返回一个新的ChainMap包含所有的当前实例的映射,除了第一个。这样可以在搜索的时候跳过第一个映射。使用的场景类似在 nested scopes 嵌套作用域中使用nonlocal关键词。用例也可以类比内建函数super() 。一个d.parents 的引用等价于ChainMap(*d.maps[1:]) 。last.parents

ChainMap({'label2': '22', 'label3': '33'}, {'label4': '44', 'label5': '55'})4、应用案例-购物清单作为使用ChainMap的第一个例子,让我们考虑一张购物清单。我们的清单可能包含玩具,电脑,甚至衣服。所有这些条目都有价格,所以我们将把我们的条目存储在名称价格映射中。toys = {'Blocks':30,'Monopoly':20}

computers = {'iMac':1000,'Chromebook':1000,'PC':400}

clothing = {'Jeans':40,'T-shirt':10}现在我们可以使用ChainMap在这些不同的集合上建立一个单一的视图:from collections import ChainMap

inventory = ChainMap(toys,computers,clothing)这使得我们可以查询清单,就像它是一个单一的字典:inventory['Monopoly']

20

inventory['Jeans']40正如官方文档所述,ChainMap支持所有常用的字典方法。我们可以使用.get()来搜索可能不存在的条目,或者使用 .pop()删除条目。inventory.get('Blocks-1')

None

inventory.get('Chromebook')

1000

inventory.pop('Blocks')

inventory

ChainMap({'Monopoly': 20}, {'iMac': 1000, 'Chromebook': 1000, 'PC': 400}, {'Jeans': 40, 'T-shirt': 10})如果我们现在把玩具添加到toys字典里,它也将在清单中可用。这是ChainMap的可更新的方面。toys['Nintendo'] = 20

inventory['Nintendo']

20Oh和ChainMap有一个恰当的字符串表示形式:str(inventory)

"ChainMap({'Monopoly': 20, 'Nintendo': 20}, {'iMac': 1000, 'Chromebook': 1000, 'PC': 400}, {'Jeans': 40, 'T-shirt': 10})"一个很好的特点是,在我们的例子中,toys, computers和clothing都是在相同的上下文中(解释器),它们可以来自完全不同的模块或包。这是因为ChainMap通过引用存储底层字典。第一个例子是使用ChainMap一次搜索多个字典。事实上,当构建ChainMap时,我们所做的就是有效地构建一系列字典。当查找清单中的一个项时,toys首先被查找,然后是computers,最后是clothing。ChainMap真的只是一个映射链!实际上,ChainMap的另一个任务是维护链的默认值。我们将以一个命令行应用程序的例子来说明这是什么意思。5、应用案例-CLI配置让我们面对现实,管理命令行应用程序的配置可能是困难的。配置来自多个源:命令行参数、环境变量、本地文件等。我们通常实施优先级的概念:如果A和B都定义参数P,A的P值将被使用,因为它的优先级高于B。例如,如果传递了命令行参数,我们可能希望在环境变量上使用命令行参数。如何轻松地管理配置源的优先级?一个答案是将所有配置源存储在ChainMap中。因为ChainMap中的查找是按顺序连续地对每个底层映射执行的(按照他们传给构造函数的顺序),所以我们可以很容易地实现我们寻找的优先级。下面是一个简单的命令行应用程序。调试参数从命令行参数、环境变量或硬编码默认值中提取:在执行脚本时,我们可以检查是否首先在命令行参数中查找debug,然后是环境变量,最后是默认值:这样看上去就非常整洁,对吧?6、我为什么关心?坦率地说,ChainMap是那些你可以忽略的Python特性之一。还有其他ChainMap的替代方案。例如,使用更新循环—例如创建一个dict并用字典update()它—可能奏效。但是,这只有在您不需要跟踪项目的起源时才有效,就像我们的多源CLI配置示例中的情况一样。但是,当你知道ChainMap存在的时候,ChainMap可以让你更轻松,你的代码更优雅。7、总结总而言之,我们一起看了ChainMap是什么,一些具体的使用示例,以及如何在现实生活中,性能关键的应用程序中使用ChainMap。如果您想了解更多关于Python的高性能数据容器的信息,请务必从Python的标准库中collections模块中查看其他出色类和函数。七、UserDict UserDict类是用作字典对象的外包装。对这个类的需求已部分由直接创建dict的子类的功能所替代;不过这个类处理起来更容易,因为底层的字典可以作为属性来访问。模拟一个字典类。这个实例的内容保存为一个正常字典,可以通过UserDict实例的data属性存取。如果提供了initialdata 值, data 就被初始化为它的内容,注意一个 initialdata 的引用不会被保留作为其他用途。UserDict 实例提供了以下属性作为扩展方法和操作的支持:data一个真实的字典,用于保存 UserDict 类的内容。八、UserList 这个类封装了列表对象。它是一个有用的基础类,对于你想自定义的类似列表的类,可以继承和覆盖现有的方法,也可以添加新的方法。这样我们可以对列表添加新的行为。对这个类的需求已部分由直接创建 list 的子类的功能所替代;不过,这个类处理起来更容易,因为底层的列表可以作为属性来访问。模拟一个列表。这个实例的内容被保存为一个正常列表,通过 UserList 的 data 属性存取。实例内容被初始化为一个 list 的copy,默认为 [] 空列表。 list可以是迭代对象,比如一个Python列表,或者一个UserList 对象。UserList 提供了以下属性作为可变序列的方法和操作的扩展:data一个 list 对象用于存储 UserList 的内容。子类化的要求: UserList 的子类需要提供一个构造器,可以无参数调用,或者一个参数调用。返回一个新序列的列表操作需要创建一个实现类的实例。它假定了构造器可以以一个参数进行调用,这个参数是一个序列对象,作为数据源。如果一个分离的类不希望依照这个需求,所有的特殊方法就必须重写;请参照源代码进行修改。 九、UserString UserString类是用作字符串对象的外包装。对这个类的需求已部分由直接创建str的子类的功能所替代,不过这个类处理起来更容易,因为底层的字符串可以作为属性来访问。模拟一个字符串对象。这个实例对象的内容保存为一个正常字符串,通过UserString的data属性存取。实例内容初始化设置为seq的copy。seq 参数可以是任何可通过内建str()函数转换为字符串的对象。UserString 提供了以下属性作为字符串方法和操作的额外支持:data一个真正的str对象用来存放 UserString 类的内容。编辑于 2022-04-08 11:36Python字典学习词频​赞同 740​​28 条评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录Python基础方法详解介绍Python的基

collections — Container datatypes — Python 3.12.2 documentation

collections — Container datatypes — Python 3.12.2 documentation

Theme

Auto

Light

Dark

Table of Contents

collections — Container datatypes

ChainMap objects

ChainMap Examples and Recipes

Counter objects

deque objects

deque Recipes

defaultdict objects

defaultdict Examples

namedtuple() Factory Function for Tuples with Named Fields

OrderedDict objects

OrderedDict Examples and Recipes

UserDict objects

UserList objects

UserString objects

Previous topic

calendar — General calendar-related functions

Next topic

collections.abc — Abstract Base Classes for Containers

This Page

Report a Bug

Show Source

Navigation

index

modules |

next |

previous |

Python »

3.12.2 Documentation »

The Python Standard Library »

Data Types »

collections — Container datatypes

|

Theme

Auto

Light

Dark

|

collections — Container datatypes¶

Source code: Lib/collections/__init__.py

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

ChainMap objects¶

New in version 3.3.

A ChainMap class is provided for quickly linking a number of mappings

so they can be treated as a single unit. It is often much faster than creating

a new dictionary and running multiple update() calls.

The class can be used to simulate nested scopes and is useful in templating.

class collections.ChainMap(*maps)¶

A ChainMap groups multiple dicts or other mappings together to

create a single, updateable view. If no maps are specified, a single empty

dictionary is provided so that a new chain always has at least one mapping.

The underlying mappings are stored in a list. That list is public and can

be accessed or updated using the maps attribute. There is no other state.

Lookups search the underlying mappings successively until a key is found. In

contrast, writes, updates, and deletions only operate on the first mapping.

A ChainMap incorporates the underlying mappings by reference. So, if

one of the underlying mappings gets updated, those changes will be reflected

in ChainMap.

All of the usual dictionary methods are supported. In addition, there is a

maps attribute, a method for creating new subcontexts, and a property for

accessing all but the first mapping:

maps¶

A user updateable list of mappings. The list is ordered from

first-searched to last-searched. It is the only stored state and can

be modified to change which mappings are searched. The list should

always contain at least one mapping.

new_child(m=None, **kwargs)¶

Returns a new ChainMap containing a new map followed by

all of the maps in the current instance. If m is specified,

it becomes the new map at the front of the list of mappings; if not

specified, an empty dict is used, so that a call to d.new_child()

is equivalent to: ChainMap({}, *d.maps). If any keyword arguments

are specified, they update passed map or new empty dict. This method

is used for creating subcontexts that can be updated without altering

values in any of the parent mappings.

Changed in version 3.4: The optional m parameter was added.

Changed in version 3.10: Keyword arguments support was added.

parents¶

Property returning a new ChainMap containing all of the maps in

the current instance except the first one. This is useful for skipping

the first map in the search. Use cases are similar to those for the

nonlocal keyword used in nested scopes. The use cases also parallel those for the built-in

super() function. A reference to d.parents is equivalent to:

ChainMap(*d.maps[1:]).

Note, the iteration order of a ChainMap() is determined by

scanning the mappings last to first:

>>> baseline = {'music': 'bach', 'art': 'rembrandt'}

>>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}

>>> list(ChainMap(adjustments, baseline))

['music', 'art', 'opera']

This gives the same ordering as a series of dict.update() calls

starting with the last mapping:

>>> combined = baseline.copy()

>>> combined.update(adjustments)

>>> list(combined)

['music', 'art', 'opera']

Changed in version 3.9: Added support for | and |= operators, specified in PEP 584.

See also

The MultiContext class

in the Enthought CodeTools package has options to support

writing to any mapping in the chain.

Django’s Context class

for templating is a read-only chain of mappings. It also features

pushing and popping of contexts similar to the

new_child() method and the

parents property.

The Nested Contexts recipe has options to control

whether writes and other mutations apply only to the first mapping or to

any mapping in the chain.

A greatly simplified read-only version of Chainmap.

ChainMap Examples and Recipes¶

This section shows various approaches to working with chained maps.

Example of simulating Python’s internal lookup chain:

import builtins

pylookup = ChainMap(locals(), globals(), vars(builtins))

Example of letting user specified command-line arguments take precedence over

environment variables which in turn take precedence over default values:

import os, argparse

defaults = {'color': 'red', 'user': 'guest'}

parser = argparse.ArgumentParser()

parser.add_argument('-u', '--user')

parser.add_argument('-c', '--color')

namespace = parser.parse_args()

command_line_args = {k: v for k, v in vars(namespace).items() if v is not None}

combined = ChainMap(command_line_args, os.environ, defaults)

print(combined['color'])

print(combined['user'])

Example patterns for using the ChainMap class to simulate nested

contexts:

c = ChainMap() # Create root context

d = c.new_child() # Create nested child context

e = c.new_child() # Child of c, independent from d

e.maps[0] # Current context dictionary -- like Python's locals()

e.maps[-1] # Root context -- like Python's globals()

e.parents # Enclosing context chain -- like Python's nonlocals

d['x'] = 1 # Set value in current context

d['x'] # Get first key in the chain of contexts

del d['x'] # Delete from current context

list(d) # All nested values

k in d # Check all nested values

len(d) # Number of nested values

d.items() # All nested items

dict(d) # Flatten into a regular dictionary

The ChainMap class only makes updates (writes and deletions) to the

first mapping in the chain while lookups will search the full chain. However,

if deep writes and deletions are desired, it is easy to make a subclass that

updates keys found deeper in the chain:

class DeepChainMap(ChainMap):

'Variant of ChainMap that allows direct updates to inner scopes'

def __setitem__(self, key, value):

for mapping in self.maps:

if key in mapping:

mapping[key] = value

return

self.maps[0][key] = value

def __delitem__(self, key):

for mapping in self.maps:

if key in mapping:

del mapping[key]

return

raise KeyError(key)

>>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})

>>> d['lion'] = 'orange' # update an existing key two levels down

>>> d['snake'] = 'red' # new keys get added to the topmost dict

>>> del d['elephant'] # remove an existing key one level down

>>> d # display result

DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})

Counter objects¶

A counter tool is provided to support convenient and rapid tallies.

For example:

>>> # Tally occurrences of words in a list

>>> cnt = Counter()

>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:

... cnt[word] += 1

...

>>> cnt

Counter({'blue': 3, 'red': 2, 'green': 1})

>>> # Find the ten most common words in Hamlet

>>> import re

>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())

>>> Counter(words).most_common(10)

[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),

('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]

class collections.Counter([iterable-or-mapping])¶

A Counter is a dict subclass for counting hashable objects.

It is a collection where elements are stored as dictionary keys

and their counts are stored as dictionary values. Counts are allowed to be

any integer value including zero or negative counts. The Counter

class is similar to bags or multisets in other languages.

Elements are counted from an iterable or initialized from another

mapping (or counter):

>>> c = Counter() # a new, empty counter

>>> c = Counter('gallahad') # a new counter from an iterable

>>> c = Counter({'red': 4, 'blue': 2}) # a new counter from a mapping

>>> c = Counter(cats=4, dogs=8) # a new counter from keyword args

Counter objects have a dictionary interface except that they return a zero

count for missing items instead of raising a KeyError:

>>> c = Counter(['eggs', 'ham'])

>>> c['bacon'] # count of a missing element is zero

0

Setting a count to zero does not remove an element from a counter.

Use del to remove it entirely:

>>> c['sausage'] = 0 # counter entry with a zero count

>>> del c['sausage'] # del actually removes the entry

New in version 3.1.

Changed in version 3.7: As a dict subclass, Counter

inherited the capability to remember insertion order. Math operations

on Counter objects also preserve order. Results are ordered

according to when an element is first encountered in the left operand

and then by the order encountered in the right operand.

Counter objects support additional methods beyond those available for all

dictionaries:

elements()¶

Return an iterator over elements repeating each as many times as its

count. Elements are returned in the order first encountered. If an

element’s count is less than one, elements() will ignore it.

>>> c = Counter(a=4, b=2, c=0, d=-2)

>>> sorted(c.elements())

['a', 'a', 'a', 'a', 'b', 'b']

most_common([n])¶

Return a list of the n most common elements and their counts from the

most common to the least. If n is omitted or None,

most_common() returns all elements in the counter.

Elements with equal counts are ordered in the order first encountered:

>>> Counter('abracadabra').most_common(3)

[('a', 5), ('b', 2), ('r', 2)]

subtract([iterable-or-mapping])¶

Elements are subtracted from an iterable or from another mapping

(or counter). Like dict.update() but subtracts counts instead

of replacing them. Both inputs and outputs may be zero or negative.

>>> c = Counter(a=4, b=2, c=0, d=-2)

>>> d = Counter(a=1, b=2, c=3, d=4)

>>> c.subtract(d)

>>> c

Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

New in version 3.2.

total()¶

Compute the sum of the counts.

>>> c = Counter(a=10, b=5, c=0)

>>> c.total()

15

New in version 3.10.

The usual dictionary methods are available for Counter objects

except for two which work differently for counters.

fromkeys(iterable)¶

This class method is not implemented for Counter objects.

update([iterable-or-mapping])¶

Elements are counted from an iterable or added-in from another

mapping (or counter). Like dict.update() but adds counts

instead of replacing them. Also, the iterable is expected to be a

sequence of elements, not a sequence of (key, value) pairs.

Counters support rich comparison operators for equality, subset, and

superset relationships: ==, !=, <, <=, >, >=.

All of those tests treat missing elements as having zero counts so that

Counter(a=1) == Counter(a=1, b=0) returns true.

New in version 3.10: Rich comparison operations were added.

Changed in version 3.10: In equality tests, missing elements are treated as having zero counts.

Formerly, Counter(a=3) and Counter(a=3, b=0) were considered

distinct.

Common patterns for working with Counter objects:

c.total() # total of all counts

c.clear() # reset all counts

list(c) # list unique elements

set(c) # convert to a set

dict(c) # convert to a regular dictionary

c.items() # convert to a list of (elem, cnt) pairs

Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs

c.most_common()[:-n-1:-1] # n least common elements

+c # remove zero and negative counts

Several mathematical operations are provided for combining Counter

objects to produce multisets (counters that have counts greater than zero).

Addition and subtraction combine counters by adding or subtracting the counts

of corresponding elements. Intersection and union return the minimum and

maximum of corresponding counts. Equality and inclusion compare

corresponding counts. Each operation can accept inputs with signed

counts, but the output will exclude results with counts of zero or less.

>>> c = Counter(a=3, b=1)

>>> d = Counter(a=1, b=2)

>>> c + d # add two counters together: c[x] + d[x]

Counter({'a': 4, 'b': 3})

>>> c - d # subtract (keeping only positive counts)

Counter({'a': 2})

>>> c & d # intersection: min(c[x], d[x])

Counter({'a': 1, 'b': 1})

>>> c | d # union: max(c[x], d[x])

Counter({'a': 3, 'b': 2})

>>> c == d # equality: c[x] == d[x]

False

>>> c <= d # inclusion: c[x] <= d[x]

False

Unary addition and subtraction are shortcuts for adding an empty counter

or subtracting from an empty counter.

>>> c = Counter(a=2, b=-4)

>>> +c

Counter({'a': 2})

>>> -c

Counter({'b': 4})

New in version 3.3: Added support for unary plus, unary minus, and in-place multiset operations.

Note

Counters were primarily designed to work with positive integers to represent

running counts; however, care was taken to not unnecessarily preclude use

cases needing other types or negative values. To help with those use cases,

this section documents the minimum range and type restrictions.

The Counter class itself is a dictionary subclass with no

restrictions on its keys and values. The values are intended to be numbers

representing counts, but you could store anything in the value field.

The most_common() method requires only that the values be orderable.

For in-place operations such as c[key] += 1, the value type need only

support addition and subtraction. So fractions, floats, and decimals would

work and negative values are supported. The same is also true for

update() and subtract() which allow negative and zero values

for both inputs and outputs.

The multiset methods are designed only for use cases with positive values.

The inputs may be negative or zero, but only outputs with positive values

are created. There are no type restrictions, but the value type needs to

support addition, subtraction, and comparison.

The elements() method requires integer counts. It ignores zero and

negative counts.

See also

Bag class

in Smalltalk.

Wikipedia entry for Multisets.

C++ multisets

tutorial with examples.

For mathematical operations on multisets and their use cases, see

Knuth, Donald. The Art of Computer Programming Volume II,

Section 4.6.3, Exercise 19.

To enumerate all distinct multisets of a given size over a given set of

elements, see itertools.combinations_with_replacement():

map(Counter, combinations_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC

deque objects¶

class collections.deque([iterable[, maxlen]])¶

Returns a new deque object initialized left-to-right (using append()) with

data from iterable. If iterable is not specified, the new deque is empty.

Deques are a generalization of stacks and queues (the name is pronounced “deck”

and is short for “double-ended queue”). Deques support thread-safe, memory

efficient appends and pops from either side of the deque with approximately the

same O(1) performance in either direction.

Though list objects support similar operations, they are optimized for

fast fixed-length operations and incur O(n) memory movement costs for

pop(0) and insert(0, v) operations which change both the size and

position of the underlying data representation.

If maxlen is not specified or is None, deques may grow to an

arbitrary length. Otherwise, the deque is bounded to the specified maximum

length. Once a bounded length deque is full, when new items are added, a

corresponding number of items are discarded from the opposite end. Bounded

length deques provide functionality similar to the tail filter in

Unix. They are also useful for tracking transactions and other pools of data

where only the most recent activity is of interest.

Deque objects support the following methods:

append(x)¶

Add x to the right side of the deque.

appendleft(x)¶

Add x to the left side of the deque.

clear()¶

Remove all elements from the deque leaving it with length 0.

copy()¶

Create a shallow copy of the deque.

New in version 3.5.

count(x)¶

Count the number of deque elements equal to x.

New in version 3.2.

extend(iterable)¶

Extend the right side of the deque by appending elements from the iterable

argument.

extendleft(iterable)¶

Extend the left side of the deque by appending elements from iterable.

Note, the series of left appends results in reversing the order of

elements in the iterable argument.

index(x[, start[, stop]])¶

Return the position of x in the deque (at or after index start

and before index stop). Returns the first match or raises

ValueError if not found.

New in version 3.5.

insert(i, x)¶

Insert x into the deque at position i.

If the insertion would cause a bounded deque to grow beyond maxlen,

an IndexError is raised.

New in version 3.5.

pop()¶

Remove and return an element from the right side of the deque. If no

elements are present, raises an IndexError.

popleft()¶

Remove and return an element from the left side of the deque. If no

elements are present, raises an IndexError.

remove(value)¶

Remove the first occurrence of value. If not found, raises a

ValueError.

reverse()¶

Reverse the elements of the deque in-place and then return None.

New in version 3.2.

rotate(n=1)¶

Rotate the deque n steps to the right. If n is negative, rotate

to the left.

When the deque is not empty, rotating one step to the right is equivalent

to d.appendleft(d.pop()), and rotating one step to the left is

equivalent to d.append(d.popleft()).

Deque objects also provide one read-only attribute:

maxlen¶

Maximum size of a deque or None if unbounded.

New in version 3.1.

In addition to the above, deques support iteration, pickling, len(d),

reversed(d), copy.copy(d), copy.deepcopy(d), membership testing with

the in operator, and subscript references such as d[0] to access

the first element. Indexed access is O(1) at both ends but slows to O(n) in

the middle. For fast random access, use lists instead.

Starting in version 3.5, deques support __add__(), __mul__(),

and __imul__().

Example:

>>> from collections import deque

>>> d = deque('ghi') # make a new deque with three items

>>> for elem in d: # iterate over the deque's elements

... print(elem.upper())

G

H

I

>>> d.append('j') # add a new entry to the right side

>>> d.appendleft('f') # add a new entry to the left side

>>> d # show the representation of the deque

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

>>> d.pop() # return and remove the rightmost item

'j'

>>> d.popleft() # return and remove the leftmost item

'f'

>>> list(d) # list the contents of the deque

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

>>> d[0] # peek at leftmost item

'g'

>>> d[-1] # peek at rightmost item

'i'

>>> list(reversed(d)) # list the contents of a deque in reverse

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

>>> 'h' in d # search the deque

True

>>> d.extend('jkl') # add multiple elements at once

>>> d

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

>>> d.rotate(1) # right rotation

>>> d

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

>>> d.rotate(-1) # left rotation

>>> d

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

>>> deque(reversed(d)) # make a new deque in reverse order

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

>>> d.clear() # empty the deque

>>> d.pop() # cannot pop from an empty deque

Traceback (most recent call last):

File "", line 1, in -toplevel-

d.pop()

IndexError: pop from an empty deque

>>> d.extendleft('abc') # extendleft() reverses the input order

>>> d

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

deque Recipes¶

This section shows various approaches to working with deques.

Bounded length deques provide functionality similar to the tail filter

in Unix:

def tail(filename, n=10):

'Return the last n lines of a file'

with open(filename) as f:

return deque(f, n)

Another approach to using deques is to maintain a sequence of recently

added elements by appending to the right and popping to the left:

def moving_average(iterable, n=3):

# moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0

# https://en.wikipedia.org/wiki/Moving_average

it = iter(iterable)

d = deque(itertools.islice(it, n-1))

d.appendleft(0)

s = sum(d)

for elem in it:

s += elem - d.popleft()

d.append(elem)

yield s / n

A round-robin scheduler can be implemented with

input iterators stored in a deque. Values are yielded from the active

iterator in position zero. If that iterator is exhausted, it can be removed

with popleft(); otherwise, it can be cycled back to the end with

the rotate() method:

def roundrobin(*iterables):

"roundrobin('ABC', 'D', 'EF') --> A D E B F C"

iterators = deque(map(iter, iterables))

while iterators:

try:

while True:

yield next(iterators[0])

iterators.rotate(-1)

except StopIteration:

# Remove an exhausted iterator.

iterators.popleft()

The rotate() method provides a way to implement deque slicing and

deletion. For example, a pure Python implementation of del d[n] relies on

the rotate() method to position elements to be popped:

def delete_nth(d, n):

d.rotate(-n)

d.popleft()

d.rotate(n)

To implement deque slicing, use a similar approach applying

rotate() to bring a target element to the left side of the deque. Remove

old entries with popleft(), add new entries with extend(), and then

reverse the rotation.

With minor variations on that approach, it is easy to implement Forth style

stack manipulations such as dup, drop, swap, over, pick,

rot, and roll.

defaultdict objects¶

class collections.defaultdict(default_factory=None, /[, ...])¶

Return a new dictionary-like object. defaultdict is a subclass of the

built-in dict class. It overrides one method and adds one writable

instance variable. The remaining functionality is the same as for the

dict class and is not documented here.

The first argument provides the initial value for the default_factory

attribute; it defaults to None. All remaining arguments are treated the same

as if they were passed to the dict constructor, including keyword

arguments.

defaultdict objects support the following method in addition to the

standard dict operations:

__missing__(key)¶

If the default_factory attribute is None, this raises a

KeyError exception with the key as argument.

If default_factory is not None, it is called without arguments

to provide a default value for the given key, this value is inserted in

the dictionary for the key, and returned.

If calling default_factory raises an exception this exception is

propagated unchanged.

This method is called by the __getitem__() method of the

dict class when the requested key is not found; whatever it

returns or raises is then returned or raised by __getitem__().

Note that __missing__() is not called for any operations besides

__getitem__(). This means that get() will, like normal

dictionaries, return None as a default rather than using

default_factory.

defaultdict objects support the following instance variable:

default_factory¶

This attribute is used by the __missing__() method; it is

initialized from the first argument to the constructor, if present, or to

None, if absent.

Changed in version 3.9: Added merge (|) and update (|=) operators, specified in

PEP 584.

defaultdict Examples¶

Using list as the default_factory, it is easy to group a

sequence of key-value pairs into a dictionary of lists:

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

>>> d = defaultdict(list)

>>> for k, v in s:

... d[k].append(v)

...

>>> sorted(d.items())

[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

When each key is encountered for the first time, it is not already in the

mapping; so an entry is automatically created using the default_factory

function which returns an empty list. The list.append()

operation then attaches the value to the new list. When keys are encountered

again, the look-up proceeds normally (returning the list for that key) and the

list.append() operation adds another value to the list. This technique is

simpler and faster than an equivalent technique using dict.setdefault():

>>> d = {}

>>> for k, v in s:

... d.setdefault(k, []).append(v)

...

>>> sorted(d.items())

[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

Setting the default_factory to int makes the

defaultdict useful for counting (like a bag or multiset in other

languages):

>>> s = 'mississippi'

>>> d = defaultdict(int)

>>> for k in s:

... d[k] += 1

...

>>> sorted(d.items())

[('i', 4), ('m', 1), ('p', 2), ('s', 4)]

When a letter is first encountered, it is missing from the mapping, so the

default_factory function calls int() to supply a default count of

zero. The increment operation then builds up the count for each letter.

The function int() which always returns zero is just a special case of

constant functions. A faster and more flexible way to create constant functions

is to use a lambda function which can supply any constant value (not just

zero):

>>> def constant_factory(value):

... return lambda: value

...

>>> d = defaultdict(constant_factory(''))

>>> d.update(name='John', action='ran')

>>> '%(name)s %(action)s to %(object)s' % d

'John ran to '

Setting the default_factory to set makes the

defaultdict useful for building a dictionary of sets:

>>> 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)

...

>>> sorted(d.items())

[('blue', {2, 4}), ('red', {1, 3})]

namedtuple() Factory Function for Tuples with Named Fields¶

Named tuples assign meaning to each position in a tuple and allow for more readable,

self-documenting code. They can be used wherever regular tuples are used, and

they add the ability to access fields by name instead of position index.

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)¶

Returns a new tuple subclass named typename. The new subclass is used to

create tuple-like objects that have fields accessible by attribute lookup as

well as being indexable and iterable. Instances of the subclass also have a

helpful docstring (with typename and field_names) and a helpful __repr__()

method which lists the tuple contents in a name=value format.

The field_names are a sequence of strings such as ['x', 'y'].

Alternatively, field_names can be a single string with each fieldname

separated by whitespace and/or commas, for example 'x y' or 'x, y'.

Any valid Python identifier may be used for a fieldname except for names

starting with an underscore. Valid identifiers consist of letters, digits,

and underscores but do not start with a digit or underscore and cannot be

a keyword such as class, for, return, global, pass,

or raise.

If rename is true, invalid fieldnames are automatically replaced

with positional names. For example, ['abc', 'def', 'ghi', 'abc'] is

converted to ['abc', '_1', 'ghi', '_3'], eliminating the keyword

def and the duplicate fieldname abc.

defaults can be None or an iterable of default values.

Since fields with a default value must come after any fields without a

default, the defaults are applied to the rightmost parameters. For

example, if the fieldnames are ['x', 'y', 'z'] and the defaults are

(1, 2), then x will be a required argument, y will default to

1, and z will default to 2.

If module is defined, the __module__ attribute of the named tuple is

set to that value.

Named tuple instances do not have per-instance dictionaries, so they are

lightweight and require no more memory than regular tuples.

To support pickling, the named tuple class should be assigned to a variable

that matches typename.

Changed in version 3.1: Added support for rename.

Changed in version 3.6: The verbose and rename parameters became

keyword-only arguments.

Changed in version 3.6: Added the module parameter.

Changed in version 3.7: Removed the verbose parameter and the _source attribute.

Changed in version 3.7: Added the defaults parameter and the _field_defaults

attribute.

>>> # Basic example

>>> Point = namedtuple('Point', ['x', 'y'])

>>> p = Point(11, y=22) # instantiate with positional or keyword arguments

>>> p[0] + p[1] # indexable like the plain tuple (11, 22)

33

>>> x, y = p # unpack like a regular tuple

>>> x, y

(11, 22)

>>> p.x + p.y # fields also accessible by name

33

>>> p # readable __repr__ with a name=value style

Point(x=11, y=22)

Named tuples are especially useful for assigning field names to result tuples returned

by the csv or sqlite3 modules:

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv

for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):

print(emp.name, emp.title)

import sqlite3

conn = sqlite3.connect('/companydata')

cursor = conn.cursor()

cursor.execute('SELECT name, age, title, department, paygrade FROM employees')

for emp in map(EmployeeRecord._make, cursor.fetchall()):

print(emp.name, emp.title)

In addition to the methods inherited from tuples, named tuples support

three additional methods and two attributes. To prevent conflicts with

field names, the method and attribute names start with an underscore.

classmethod somenamedtuple._make(iterable)¶

Class method that makes a new instance from an existing sequence or iterable.

>>> t = [11, 22]

>>> Point._make(t)

Point(x=11, y=22)

somenamedtuple._asdict()¶

Return a new dict which maps field names to their corresponding

values:

>>> p = Point(x=11, y=22)

>>> p._asdict()

{'x': 11, 'y': 22}

Changed in version 3.1: Returns an OrderedDict instead of a regular dict.

Changed in version 3.8: Returns a regular dict instead of an OrderedDict.

As of Python 3.7, regular dicts are guaranteed to be ordered. If the

extra features of OrderedDict are required, the suggested

remediation is to cast the result to the desired type:

OrderedDict(nt._asdict()).

somenamedtuple._replace(**kwargs)¶

Return a new instance of the named tuple replacing specified fields with new

values:

>>> p = Point(x=11, y=22)

>>> p._replace(x=33)

Point(x=33, y=22)

>>> for partnum, record in inventory.items():

... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())

somenamedtuple._fields¶

Tuple of strings listing the field names. Useful for introspection

and for creating new named tuple types from existing named tuples.

>>> p._fields # view the field names

('x', 'y')

>>> Color = namedtuple('Color', 'red green blue')

>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)

>>> Pixel(11, 22, 128, 255, 0)

Pixel(x=11, y=22, red=128, green=255, blue=0)

somenamedtuple._field_defaults¶

Dictionary mapping field names to default values.

>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])

>>> Account._field_defaults

{'balance': 0}

>>> Account('premium')

Account(type='premium', balance=0)

To retrieve a field whose name is stored in a string, use the getattr()

function:

>>> getattr(p, 'x')

11

To convert a dictionary to a named tuple, use the double-star-operator

(as described in Unpacking Argument Lists):

>>> d = {'x': 11, 'y': 22}

>>> Point(**d)

Point(x=11, y=22)

Since a named tuple is a regular Python class, it is easy to add or change

functionality with a subclass. Here is how to add a calculated field and

a fixed-width print format:

>>> class Point(namedtuple('Point', ['x', 'y'])):

... __slots__ = ()

... @property

... def hypot(self):

... return (self.x ** 2 + self.y ** 2) ** 0.5

... def __str__(self):

... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)

>>> for p in Point(3, 4), Point(14, 5/7):

... print(p)

Point: x= 3.000 y= 4.000 hypot= 5.000

Point: x=14.000 y= 0.714 hypot=14.018

The subclass shown above sets __slots__ to an empty tuple. This helps

keep memory requirements low by preventing the creation of instance dictionaries.

Subclassing is not useful for adding new, stored fields. Instead, simply

create a new named tuple type from the _fields attribute:

>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))

Docstrings can be customized by making direct assignments to the __doc__

fields:

>>> Book = namedtuple('Book', ['id', 'title', 'authors'])

>>> Book.__doc__ += ': Hardcover book in active collection'

>>> Book.id.__doc__ = '13-digit ISBN'

>>> Book.title.__doc__ = 'Title of first printing'

>>> Book.authors.__doc__ = 'List of authors sorted by last name'

Changed in version 3.5: Property docstrings became writeable.

See also

See typing.NamedTuple for a way to add type hints for named

tuples. It also provides an elegant notation using the class

keyword:

class Component(NamedTuple):

part_number: int

weight: float

description: Optional[str] = None

See types.SimpleNamespace() for a mutable namespace based on an

underlying dictionary instead of a tuple.

The dataclasses module provides a decorator and functions for

automatically adding generated special methods to user-defined classes.

OrderedDict objects¶

Ordered dictionaries are just like regular dictionaries but have some extra

capabilities relating to ordering operations. They have become less

important now that the built-in dict class gained the ability

to remember insertion order (this new behavior became guaranteed in

Python 3.7).

Some differences from dict still remain:

The regular dict was designed to be very good at mapping

operations. Tracking insertion order was secondary.

The OrderedDict was designed to be good at reordering operations.

Space efficiency, iteration speed, and the performance of update

operations were secondary.

The OrderedDict algorithm can handle frequent reordering operations

better than dict. As shown in the recipes below, this makes it

suitable for implementing various kinds of LRU caches.

The equality operation for OrderedDict checks for matching order.

A regular dict can emulate the order sensitive equality test with

p == q and all(k1 == k2 for k1, k2 in zip(p, q)).

The popitem() method of OrderedDict has a different

signature. It accepts an optional argument to specify which item is popped.

A regular dict can emulate OrderedDict’s od.popitem(last=True)

with d.popitem() which is guaranteed to pop the rightmost (last) item.

A regular dict can emulate OrderedDict’s od.popitem(last=False)

with (k := next(iter(d)), d.pop(k)) which will return and remove the

leftmost (first) item if it exists.

OrderedDict has a move_to_end() method to efficiently

reposition an element to an endpoint.

A regular dict can emulate OrderedDict’s od.move_to_end(k,

last=True) with d[k] = d.pop(k) which will move the key and its

associated value to the rightmost (last) position.

A regular dict does not have an efficient equivalent for

OrderedDict’s od.move_to_end(k, last=False) which moves the key

and its associated value to the leftmost (first) position.

Until Python 3.8, dict lacked a __reversed__() method.

class collections.OrderedDict([items])¶

Return an instance of a dict subclass that has methods

specialized for rearranging dictionary order.

New in version 3.1.

popitem(last=True)¶

The popitem() method for ordered dictionaries returns and removes a

(key, value) pair. The pairs are returned in

LIFO order if last is true

or FIFO order if false.

move_to_end(key, last=True)¶

Move an existing key to either end of an ordered dictionary. The item

is moved to the right end if last is true (the default) or to the

beginning if last is false. Raises KeyError if the key does

not exist:

>>> d = OrderedDict.fromkeys('abcde')

>>> d.move_to_end('b')

>>> ''.join(d)

'acdeb'

>>> d.move_to_end('b', last=False)

>>> ''.join(d)

'bacde'

New in version 3.2.

In addition to the usual mapping methods, ordered dictionaries also support

reverse iteration using reversed().

Equality tests between OrderedDict objects are order-sensitive

and are implemented as list(od1.items())==list(od2.items()).

Equality tests between OrderedDict objects and other

Mapping objects are order-insensitive like regular

dictionaries. This allows OrderedDict objects to be substituted

anywhere a regular dictionary is used.

Changed in version 3.5: The items, keys, and values views

of OrderedDict now support reverse iteration using reversed().

Changed in version 3.6: With the acceptance of PEP 468, order is retained for keyword arguments

passed to the OrderedDict constructor and its update()

method.

Changed in version 3.9: Added merge (|) and update (|=) operators, specified in PEP 584.

OrderedDict Examples and Recipes¶

It is straightforward to create an ordered dictionary variant

that remembers the order the keys were last inserted.

If a new entry overwrites an existing entry, the

original insertion position is changed and moved to the end:

class LastUpdatedOrderedDict(OrderedDict):

'Store items in the order the keys were last added'

def __setitem__(self, key, value):

super().__setitem__(key, value)

self.move_to_end(key)

An OrderedDict would also be useful for implementing

variants of functools.lru_cache():

from collections import OrderedDict

from time import time

class TimeBoundedLRU:

"LRU Cache that invalidates and refreshes old entries."

def __init__(self, func, maxsize=128, maxage=30):

self.cache = OrderedDict() # { args : (timestamp, result)}

self.func = func

self.maxsize = maxsize

self.maxage = maxage

def __call__(self, *args):

if args in self.cache:

self.cache.move_to_end(args)

timestamp, result = self.cache[args]

if time() - timestamp <= self.maxage:

return result

result = self.func(*args)

self.cache[args] = time(), result

if len(self.cache) > self.maxsize:

self.cache.popitem(0)

return result

class MultiHitLRUCache:

""" LRU cache that defers caching a result until

it has been requested multiple times.

To avoid flushing the LRU cache with one-time requests,

we don't cache until a request has been made more than once.

"""

def __init__(self, func, maxsize=128, maxrequests=4096, cache_after=1):

self.requests = OrderedDict() # { uncached_key : request_count }

self.cache = OrderedDict() # { cached_key : function_result }

self.func = func

self.maxrequests = maxrequests # max number of uncached requests

self.maxsize = maxsize # max number of stored return values

self.cache_after = cache_after

def __call__(self, *args):

if args in self.cache:

self.cache.move_to_end(args)

return self.cache[args]

result = self.func(*args)

self.requests[args] = self.requests.get(args, 0) + 1

if self.requests[args] <= self.cache_after:

self.requests.move_to_end(args)

if len(self.requests) > self.maxrequests:

self.requests.popitem(0)

else:

self.requests.pop(args, None)

self.cache[args] = result

if len(self.cache) > self.maxsize:

self.cache.popitem(0)

return result

UserDict objects¶

The class, UserDict acts as a wrapper around dictionary objects.

The need for this class has been partially supplanted by the ability to

subclass directly from dict; however, this class can be easier

to work with because the underlying dictionary is accessible as an

attribute.

class collections.UserDict([initialdata])¶

Class that simulates a dictionary. The instance’s contents are kept in a

regular dictionary, which is accessible via the data attribute of

UserDict instances. If initialdata is provided, data is

initialized with its contents; note that a reference to initialdata will not

be kept, allowing it to be used for other purposes.

In addition to supporting the methods and operations of mappings,

UserDict instances provide the following attribute:

data¶

A real dictionary used to store the contents of the UserDict

class.

UserList objects¶

This class acts as a wrapper around list objects. It is a useful base class

for your own list-like classes which can inherit from them and override

existing methods or add new ones. In this way, one can add new behaviors to

lists.

The need for this class has been partially supplanted by the ability to

subclass directly from list; however, this class can be easier

to work with because the underlying list is accessible as an attribute.

class collections.UserList([list])¶

Class that simulates a list. The instance’s contents are kept in a regular

list, which is accessible via the data attribute of UserList

instances. The instance’s contents are initially set to a copy of list,

defaulting to the empty list []. list can be any iterable, for

example a real Python list or a UserList object.

In addition to supporting the methods and operations of mutable sequences,

UserList instances provide the following attribute:

data¶

A real list object used to store the contents of the

UserList class.

Subclassing requirements: Subclasses of UserList are expected to

offer a constructor which can be called with either no arguments or one

argument. List operations which return a new sequence attempt to create an

instance of the actual implementation class. To do so, it assumes that the

constructor can be called with a single parameter, which is a sequence object

used as a data source.

If a derived class does not wish to comply with this requirement, all of the

special methods supported by this class will need to be overridden; please

consult the sources for information about the methods which need to be provided

in that case.

UserString objects¶

The class, UserString acts as a wrapper around string objects.

The need for this class has been partially supplanted by the ability to

subclass directly from str; however, this class can be easier

to work with because the underlying string is accessible as an

attribute.

class collections.UserString(seq)¶

Class that simulates a string object. The instance’s

content is kept in a regular string object, which is accessible via the

data attribute of UserString instances. The instance’s

contents are initially set to a copy of seq. The seq argument can

be any object which can be converted into a string using the built-in

str() function.

In addition to supporting the methods and operations of strings,

UserString instances provide the following attribute:

data¶

A real str object used to store the contents of the

UserString class.

Changed in version 3.5: New methods __getnewargs__, __rmod__, casefold,

format_map, isprintable, and maketrans.

Table of Contents

collections — Container datatypes

ChainMap objects

ChainMap Examples and Recipes

Counter objects

deque objects

deque Recipes

defaultdict objects

defaultdict Examples

namedtuple() Factory Function for Tuples with Named Fields

OrderedDict objects

OrderedDict Examples and Recipes

UserDict objects

UserList objects

UserString objects

Previous topic

calendar — General calendar-related functions

Next topic

collections.abc — Abstract Base Classes for Containers

This Page

Report a Bug

Show Source

«

Navigation

index

modules |

next |

previous |

Python »

3.12.2 Documentation »

The Python Standard Library »

Data Types »

collections — Container datatypes

|

Theme

Auto

Light

Dark

|

© Copyright 2001-2024, Python Software Foundation.

This page is licensed under the Python Software Foundation License Version 2.

Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.

See History and License for more information.

The Python Software Foundation is a non-profit corporation.

Please donate.

Last updated on Mar 08, 2024 (03:05 UTC).

Found a bug?

Created using Sphinx 7.2.6.

Python中 collections模块的详细用法介绍_python collections-CSDN博客

>

Python中 collections模块的详细用法介绍_python collections-CSDN博客

Python中 collections模块的详细用法介绍

最新推荐文章于 2024-03-05 10:15:42 发布

Python热爱者

最新推荐文章于 2024-03-05 10:15:42 发布

阅读量2.6w

收藏

300

点赞数

62

分类专栏:

Python基础

文章标签:

python

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/qdpython/article/details/120786550

版权

Python基础

专栏收录该内容

89 篇文章

60 订阅

订阅专栏

1. 介绍

collections是Python内建的一个集合模块,提供了许多有用的集合类和方法。

可以把它理解为一个容器,里面提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。

import collections

print(dir(collections))

# ['ChainMap', 'Counter', 'Mapping', 'MutableMapping', 'OrderedDict', 'UserDict', 'UserList', 'UserString', '_Link', '_OrderedDictItemsView', '_OrderedDictKeysView', '_OrderedDictValuesView', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__getattr__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_chain', '_collections_abc', '_count_elements', '_eq', '_heapq', '_iskeyword', '_itemgetter', '_nt_itemgetters', '_proxy', '_recursive_repr', '_repeat', '_starmap', '_sys', 'abc', 'defaultdict', 'deque', 'namedtuple']

里面有许多方法,我们只介绍常用的方法。

2.常用方法

namedtuple() : 创建一个命名元组子类的工厂函数deque :    高效增删改双向列表,类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)defaultdict : 当字典查询时,为key不存在提供一个默认值。OrderedDict : 有序词典,就是记住了插入顺序Counter : 计数功能

1. namedtuple() 命名元组

参数

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

typename :  命名的名字,返回一个新的元组子类,名为 typenamefield_names : 可以是一个[‘x’, ‘y’]这样的序列,也可以是’x, y’或者’x y’rename :   python3.1添加,如果 rename 为真, 无效域名会自动转换成位置名。比如 [‘abc’, ‘def’, ‘ghi’, ‘abc’] 转换成 [‘abc’, ‘_1’, ‘ghi’, ‘_3’] , 消除关键词 def 和重复域名 abc 。defaults :  python3.7添加, defaults 可以为 None 或者是一个默认值的 iterable(可迭代对象)。如果一个默认值域必须跟其他没有默认值的域在一起出现, defaults 就应用到最右边的参数。比如如果域名 [‘x’, ‘y’, ‘z’] 和默认值 (1, 2) ,那么 x 就必须指定一个参数值 ,y 默认值 1 , z 默认值 2 。module :   python3.6添加,如果 module 值有定义,命名元组的 __module__属性值就被设置。

使用

例如我想定义一个点(x, y),可以给它起个名字为Points

'''

学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025

寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

'''

import collections

point = collections.namedtuple('Points', ['x', 'y'])

p1 = point(2, 3)

p2 = point(4, 2)

print(p1) # Points(x=2, y=3)

print(p2) # Points(x=4, y=2)

用 isinstance 判断其类型

print(isinstance(p1, point)) # True

print(isinstance(p1, tuple)) # True

可以发现它即属于 point 类型,也属于 tuple 类型。

使用 _make 赋值

a= [11, 3]

p1._make(a)

print(p1) # Points(x=11, y=3)

使用 _replace 更改值

p1._replace(x=5)

print(p1) # Points(x=5, y=3)

2. deque 双端队列

参数

collections.deque([iterable[, maxlen]])

返回一个新的双向队列对象,从左到右初始化(用方法 append()) ,从 iterable (迭代对象) 数据创建。如果 iterable 没有指定,新队列为空。

iterable :迭代对象,可以是字符串,列表等可迭代对象。maxlen : maxlen 没有指定或者是 None , deque 可以增长到任意长度。否则, deque 就限定到指定最大长度。一旦限定长度的 deque 满了,当新项加入时,同样数量的项就从另一端弹出。

使用

'''

学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025

寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

'''

from collections import deque

q = deque(['a', 'b', 'c'], maxlen=10)

# 从右边添加一个元素

q.append('d')

print(q) # deque(['a', 'b', 'c', 'd'], maxlen=10)

# 从左边删除一个元素

print(q.popleft()) # a

print(q) # deque(['b', 'c', 'd'], maxlen=10)

# 扩展队列

q.extend(['i', 'j'])

print(q) # deque(['b', 'c', 'd', 'i', 'j'], maxlen=10)

# 查找下标

print(q.index('c')) # 1

# 移除第一个'd'

q.remove('d')

print(q) # deque(['b', 'c', 'i', 'j'], maxlen=10)

# 逆序

q.reverse()

print(q) # deque(['j', 'i', 'c', 'b'], maxlen=10)

# 最大长度

print(q.maxlen) # 10

全部方法

append(x):添加 x 到右端。

appendleft(x):添加 x 到左端。

clear():移除所有元素,使其长度为0.

copy():创建一份浅拷贝。3.5 新版功能.

count(x):计算deque中个数等于 x 的元素。3.2 新版功能.

extend(iterable):扩展deque的右侧,通过添加iterable参数中的元素。

extendleft(iterable):扩展deque的左侧,通过添加iterable参数中的元素。注意,左添加时,在结果中iterable参数中的顺序将被反过来添加。

index(x[, start[, stop]]):返回第 x 个元素(从 start 开始计算,在 stop 之前)。返回第一个匹配,如果没找到的话,升起 ValueError 。3.5 新版功能.

insert(i, x):在位置 i 插入 x 。如果插入会导致一个限长deque超出长度 maxlen 的话,就升起一个 IndexError 。3.5 新版功能.

pop():移去并且返回一个元素,deque最右侧的那一个。如果没有元素的话,就升起 IndexError 索引错误。

popleft():移去并且返回一个元素,deque最左侧的那一个。如果没有元素的话,就升起 IndexError 索引错误。

remove(value):移去找到的第一个 value。 如果没有的话就升起 ValueError 。

reverse():将deque逆序排列。返回 None 。3.2 新版功能.

rotate(n=1):向右循环移动 n 步。 如果 n 是负数,就向左循环。如果deque不是空的,向右循环移动一步就等价于 d.appendleft(d.pop()) , 向左循环一步就等价于 d.append(d.popleft()) 。

Deque对象同样提供了一个只读属性:

maxlen:Deque的最大尺寸,如果没有限定的话就是 None 。

3. defaultdict 默认值字典

使用

当key不存在时返回默认值

from collections import defaultdict

dd = defaultdict(lambda: 'not exist')

dd['key1'] = 'abc'

print(dd['key1']) # key1存在

# 'abc'

print(dd['key2']) # key2不存在,返回默认值

# 'not exist'

使用 list 作为 default_factory ,很容易将序列作为键值对加入字典:

'''

学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025

寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

'''

from collections import defaultdict

d = defaultdict(list)

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

for k, v in s:

d[k].append(v)

print(d) # defaultdict(, {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]})

相当于

d = {}

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

for k, v in s:

d.setdefault(k, []).append(v)

print(d) # {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}

设置 default_factory 为 int ,可以很好的用于计数

s = 'mississippi'

d = defaultdict(int)

for k in s:

d[k] += 1

print(d) # defaultdict(, {'m': 1, 'i': 4, 's': 4, 'p': 2})

4. OrderedDict 有序字典

有序词典就像常规词典一样,但有一些与排序操作相关的额外功能。

但是内置的 dict 类已经有了记住插入顺序的能力(在 Python 3.7 中保证了这种新行为),所以它变得不那么重要了。

使用

popitem(last=True) :有序字典的 popitem() 方法移除并返回一个 (key, value) 键值对。 如果 last 值为真,则按 LIFO 后进先出的顺序返回键值对,否则就按 FIFO 先进先出的顺序返回键值对。

'''

学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025

寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

'''

from collections import OrderedDict

d = OrderedDict(a=1, b=2, c=3, d=4,e=5)

print(d) # OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)])

print(d.popitem(last=True)) # ('e', 5)

print(d.popitem(last=False)) # ('a', 1)

print(d) # OrderedDict([('b', 2), ('c', 3), ('d', 4)]

move_to_end(key, last=True):将现有 key 移动到有序字典的任一端。 如果 last 为真值(默认)则将元素移至末尾;如果 last 为假值则将元素移至开头。如果 key 不存在则会触发 KeyError。

from collections import OrderedDict

d = OrderedDict(a=1, b=2, c=3, d=4,e=5)

print(d) # OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)])

d.move_to_end(key='c', last=True)

print(d) # OrderedDict([('a', 1), ('b', 2), ('d', 4), ('e', 5), ('c', 3)])

d.move_to_end(key='b', last=False)

print(d) # OrderedDict([('b', 2), ('a', 1), ('d', 4), ('e', 5), ('c', 3)])

5. Counter 计数

Counter 是一个 dict 的子类,用于计数可哈希对象。特别方便!

使用

字符串

from collections import Counter

c = Counter()

for i in 'sfsadfsdjklgsdla':

c[i] += 1

print(isinstance(c,Counter)) # True

print(isinstance(c,dict)) # True

print(c) # Counter({'s': 4, 'd': 3, 'f': 2, 'a': 2, 'l': 2, 'j': 1, 'k': 1, 'g': 1})

c2 = Counter('asfjslfjsdlfjgkls')

print(c2) # Counter({'s': 4, 'd': 3, 'f': 2, 'a': 2, 'l': 2, 'j': 1, 'k': 1, 'g': 1})

列表

'''

学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025

寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

'''

from collections import Counter

c = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])

print(c) # Counter({'blue': 3, 'red': 2, 'green': 1})

elements() :返回一个迭代器,其中每个元素将重复出现计数值所指定次。 元素会按首次出现的顺序返回。 如果一个元素的计数值小于一, elements() 将会忽略它。

c = Counter(a=4, b=2, c=0, d=-2)

print(sorted(c.elements())) # ['a', 'a', 'a', 'a', 'b', 'b']

most_common([n]) :返回一个列表,其中包含 n 个最常见的元素及出现次数,按常见程度由高到低排序。 如果 n 被省略或为 None, most_common() 将返回计数器中的 所有 元素。 计数值相等的元素按首次出现的顺序排序:

c = Counter('abracadabra')

print(c.most_common(3)) # [('a', 5), ('b', 2), ('r', 2)]

subtract([iterable-or-mapping]) :从 迭代对象 或 映射对象 减去元素。像 dict.update() 但是是减去,而不是替换。输入和输出都可以是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, 'b': 0, 'c': -3, 'd': -6})

优惠劵

Python热爱者

关注

关注

62

点赞

300

收藏

觉得还不错?

一键收藏

知道了

4

评论

Python中 collections模块的详细用法介绍

1. 介绍collections是Python内建的一个集合模块,提供了许多有用的集合类和方法。可以把它理解为一个容器,里面提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。import collectionsprint(dir(collections))# ['ChainMap', 'Counter', 'Mapping', 'MutableMapping', 'OrderedDict', 'UserDict', 'UserList', 'Use

复制链接

扫一扫

专栏目录

python内置模块collections知识点总结

09-18

主要介绍了python内置模块collections知识点总结,有兴趣的朋友们学习下。

了解一下python内建模块collections

01-19

在使用Python的过程中,一定是离不开数据结构的, 也就是List-列表,Tuples-元组,Dictionaries-字典。

那实际应用中我们更多的还是要去操作这些结构里的数据。比如,在列表后面添加元素,那么就会用到append() 方法。

那除了这些本身的操作方法之外,还有一个Python内建模块——collections,也提供了不少使用的方法,今天来捋一下。

一、Counter

这是一个计数器,我们可以用来方便的统计出一些元素出现的次数,比如String、List、Tuples等等。

String

from collections import Counter

c = Counte

4 条评论

您还未登录,请先

登录

后发表或查看评论

python中的 collections 模块(用法、详解、底层原理,示例等)

Mogul的博客

06-05

2404

# python中的 collections 模块

## 1、collections 模块中的 defaultdict

### 1.1 defaultdict 功能

`可以设置一个默认值作为字典中新key的默认值。该默认值可以是任何对象,

包括函数、列表、元组、集合等。默认值不需要像dict那样事先定义,因为它在需要的时候会自动创建`

`使用defaultdict,可以简化代码并提高代码的可读性,而且可以防止KeyError异常的出现。同时,defaultdict的性能与普通字典相当,因为底层实现并不

每日一课 | 详解collections工具库,一篇文章全搞定!

sinat_32849897的博客

09-18

318

作者:梁唐今日知识点collections正文前言大家好,今天为大家介绍Python当中一个很好用也是很基础的工具库,叫做collectionscollection在英文当中有容器的意...

Python入门:Python模块collections

ysds20211402的博客

01-20

1911

转自:微点阅读https://www.weidianyuedu.com/content/1817388341618.html

Python的内置模块collections有几个关键的数据结构,平常在使用的时候,开发者可以直接调用,不需要自己重复制造轮子,这样可以提高开发效率。

1. deque双端队列平常我们使用的python内置list类的append,extend,pop方法都是从list的尾部执行的(pop()默认弹出最后一个元素)。在使用的时候,list很像是一种栈结构(LIFO)。不同..

[编程基础] Python内置模块collections使用笔记

You and Me

09-05

346

collections是Python标准库中的一个内置模块,它提供了一些额外的数据结构类型,用于增强Python基础类型如列表(list)、元组(tuple)和字典(dict)等。本文主要介绍这些数据类的基础使用方法,以更好地利用Python的collections模块来处理不同类型的数据。。

Python库collections

如渊的博客

06-25

8038

官方说法:collections模块实现了特定目标的容器,以提供Python标准内建容器dict ,list , set , 和tuple的替代选择。通俗说法:Python内置的数据类型和方法,collections模块在这些内置类型的基础提供了额外的高性能数据类型,比如基础的字典是不支持顺序的,collections模块的OrderedDict类构建的字典可以支持顺序,collections模块的这些扩展的类用处非常大,熟练掌握该模块,可以大大简化Python代码,提高Python代码逼格和效率,高手入门

python3 collections模块_Python3 collections模块的使用

weixin_39790102的博客

11-30

516

collections介绍collections是Python内建的一个集合模块,提供了许多有用的集合类和方法。可以把它理解为一个容器,里面提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。importcollectionsprint(dir(collections))#['ChainMap', 'Counter', 'Mapping', 'Muta...

python之collections

Stay fool & simple

10-17

999

collections是日常工作中的重点、高频模块,包含了一些特殊的容器,针对Python内置的容器,例如list、dict、set和tuple,常用类型有:

namedtuple,可以创建包含名称的tuple;

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

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

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

defaultdict,dict的子类,可以调用提供默认值的函数;

default_fa

Python collections 模块介绍

weixin_43632687的博客

12-19

1597

1.简介

collections 是 python 的内置模块,提供了很多方便且高性能的关于集合的操作,掌握这些知识有助于提高代码的性能和可读性。

2.常用功能

2.1 namedtuple 功能详解

namedtuple() 返回一个新的元组子类,且规定了元组的元素的个数,同时除了使用下标获取元素之外,还可以通过属性直接获取。

from collections import namedtuple...

python容器数据类型 --- collections 详解

大帅的博客

08-18

405

collections 是python3中的一个标准库,提供了9种容器用来解决特定的问题

namedtuple()

创建命名元组子类的工厂函数

deque

类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)

ChainMap

类似字典(dict)的容器类,将多个映射集合到一个视图里面

Counter

字典的子类,提供了可哈

简单掌握Python的Collections模块中counter结构的用法

09-21

counter数据结构被用来提供技术功能,形式类似于Python中内置的字典结构,这里通过几个小例子来简单掌握Python的Collections模块中counter结构的用法:

python re模块的高级用法详解

12-24

总结

以上所述是小编给大家介绍的python re模块的高级用法详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对软件开发网网站的支持!

您可能感兴趣的文章:python下os模块强大的重命名方法renames详解python模块之re正则表达式详解python模块简介之有序字典(OrderedDict)Python 使用requests模块发送GET和POST请求的实现代码在Python中通过threading模块定义和调用线程的方法Python的collections模块中的OrderedDic

Python安装依赖(包)模块方法详解

12-20

Python模块,简单说就是一个.py文件,其中可以包含我们需要的任意Python代码。迄今为止,我们所编写的所有程序都包含在单独的.py文件中,因此,它们既是程序,同时也是模块。关键的区别在于,程序的设计目标是运行,而模块的设计目标是由其他程序导入并使用。

不是所有程序都有相关联的.py文件-比如说,sys模块就内置于Python中,还有些模块是使用其他语言(最常见的是C语言)实现的。不过,Python的大多数库文件都是使用Python实现的,因此,比如说,我们使用了语句import collections,之后就可以通过调用collections.namedtuple()创建命名的元组,而

Python collections.defaultdict模块用法详解

09-16

主要介绍了Python collections.defaultdict模块用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

Python collections模块使用方法详解

09-18

主要介绍了Python collections模块使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

简介Python的collections模块中defaultdict类型的用法

09-21

里我们来简介Python的collections模块中defaultdict类型的用法,与内置的字典类最大的不同在于初始化上,一起来看一下:

Python collections模块的使用方法

12-16

collections模块 这个模块实现了特定目标的容器,以提供Python标准内建容器 dict、list、set、tuple 的替代选择。 Counter:字典的子类,提供了可哈希对象的计数功能 defaultdict:字典的子类,提供了一个工厂函数...

Scrapy与分布式开发(3):Scrapy核心组件与运行机制

最新发布

九月镇领将的博客

03-05

1127

Scrapy是一个为了爬取网站数据、提取结构性数据而编写的应用框架。它使用Python语言编写,并基于异步网络框架Twisted来实现高性能的爬虫。Scrapy最初是为了页面抓取(更确切地说是网络抓取)而设计的,但它也可以用于获取API返回的数据或通用的网络爬虫。

python中collections库用法详解

04-01

collections是Python内置库中的一个模块,它提供了一些有用的类,用于处理Python中的集合类型。这些类包括:Counter、defaultdict、deque、namedtuple等。

1. Counter类

Counter类是一个用于计数的容器,它可以统计元素出现的次数。可以使用它来创建一个字典,其中字典的键是元素,值是元素的数量。Counter类的用法如下:

```python

from collections import Counter

# 创建一个Counter对象

c = Counter(['a', 'b', 'c', 'a', 'b', 'a'])

# 统计元素出现的次数

print(c) # Counter({'a': 3, 'b': 2, 'c': 1})

# 统计前n个出现次数最多的元素

print(c.most_common(2)) # [('a', 3), ('b', 2)]

```

2. defaultdict类

defaultdict类是一个字典类型,它可以自动为不存在的键分配一个默认值。当使用一个不存在的键时,它会自动创建一个默认值,并返回它。defaultdict类的用法如下:

```python

from collections import defaultdict

# 创建一个defaultdict对象

d = defaultdict(int)

# 添加键值对

d['a'] = 1

d['b'] = 2

# 访问不存在的键

print(d['c']) # 0

```

3. deque类

deque类是一个双向队列,它可以在队列的两端进行插入和删除操作。deque类的用法如下:

```python

from collections import deque

# 创建一个deque对象

d = deque()

# 在队列的左边插入元素

d.appendleft(1)

d.appendleft(2)

# 在队列的右边插入元素

d.append(3)

d.append(4)

# 访问队列中的元素

print(d) # deque([2, 1, 3, 4])

# 从队列的左边删除元素

print(d.popleft()) # 2

# 从队列的右边删除元素

print(d.pop()) # 4

```

4. namedtuple类

namedtuple类是一个工厂函数,它可以用来创建一个具有字段名的元组。该类返回的是一个元组子类,它可以像普通元组一样访问元素,但也可以使用字段名来访问元素。namedtuple类的用法如下:

```python

from collections import namedtuple

# 定义一个namedtuple类型

Point = namedtuple('Point', ['x', 'y'])

# 创建一个Point对象

p = Point(1, 2)

# 访问元素

print(p.x) # 1

print(p.y) # 2

```

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

非常没帮助

没帮助

一般

有帮助

非常有帮助

提交

Python热爱者

CSDN认证博客专家

CSDN认证企业博客

码龄5年

暂无认证

1232

原创

5637

周排名

411

总排名

454万+

访问

等级

2万+

积分

2086

粉丝

3410

获赞

295

评论

1万+

收藏

私信

关注

热门文章

【Python教程】删除字符串中字符的四种方法

107516

5种Python逐行读取文件的方式

72126

python基础:try...except...的详细用法

64197

Python字典(dict )的几种遍历方式

57945

python创建数组的详细操作方法

51840

分类专栏

python练习题

37篇

Python常用模块

27篇

爬虫

5篇

Python基础

89篇

正则

3篇

面试题

1篇

最新评论

Python 模块的加载顺序

CSDN-Ada助手:

不知道 Python入门 技能树是否可以帮到你:https://edu.csdn.net/skill/python?utm_source=AI_act_python

Python 使用 win32com 模块对 word 文件进行操作

心做し774:

如何插入图片

python函数的两种嵌套方法

顽固的小太阳:

不会打印出7 4嘛?

Python中 collections模块的详细用法介绍

liangxiao_Lv:

确实,我还想了半天为什么我的p1没变

Python学习:魔法函数

shouxiedaishit:

加群了,可以同意一下吗?

您愿意向朋友推荐“博客详情页”吗?

强烈不推荐

不推荐

一般般

推荐

强烈推荐

提交

最新文章

Python可迭代序列反转

Python 模块的加载顺序

python中字符串格式判断

2024年29篇

2023年424篇

2022年580篇

2021年790篇

2020年554篇

2019年459篇

目录

目录

分类专栏

python练习题

37篇

Python常用模块

27篇

爬虫

5篇

Python基础

89篇

正则

3篇

面试题

1篇

目录

评论 4

被折叠的  条评论

为什么被折叠?

到【灌水乐园】发言

查看更多评论

添加红包

祝福语

请填写红包祝福语或标题

红包数量

红包个数最小为10个

红包总金额

红包金额最低5元

余额支付

当前余额3.43元

前往充值 >

需支付:10.00元

取消

确定

下一步

知道了

成就一亿技术人!

领取后你会自动成为博主和红包主的粉丝

规则

hope_wisdom 发出的红包

实付元

使用余额支付

点击重新获取

扫码支付

钱包余额

0

抵扣说明:

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

余额充值

collections - 廖雪峰的官方网站

collections - 廖雪峰的官方网站

Index

廖雪峰的官方网站

Blog

Java教程

手写Spring

手写Tomcat

Makefile教程

Python教程

JavaScript教程

区块链教程

SQL教程

Git教程

文章

问答

More

Java教程

手写Spring

手写Tomcat

Makefile教程

Python教程

JavaScript教程

区块链教程

SQL教程

Git教程

文章

问答

Java教程

手写Spring

手写Tomcat

Makefile教程

Python教程

JavaScript教程

区块链教程

SQL教程

Git教程

文章

问答

 

Profile

Passkey

Sign Out

Sign In

English

简体中文

Index

Python教程

Python简介

安装Python

Python解释器

第一个Python程序

使用文本编辑器

Python代码运行助手

输入和输出

Python基础

数据类型和变量

字符串和编码

使用list和tuple

条件判断

模式匹配

循环

使用dict和set

函数

调用函数

定义函数

函数的参数

递归函数

高级特性

切片

迭代

列表生成式

生成器

迭代器

函数式编程

高阶函数

map/reduce

filter

sorted

返回函数

匿名函数

装饰器

偏函数

模块

使用模块

安装第三方模块

面向对象编程

类和实例

访问限制

继承和多态

获取对象信息

实例属性和类属性

面向对象高级编程

使用__slots__

使用@property

多重继承

定制类

使用枚举类

使用元类

错误、调试和测试

错误处理

调试

单元测试

文档测试

IO编程

文件读写

StringIO和BytesIO

操作文件和目录

序列化

进程和线程

多进程

多线程

ThreadLocal

进程 vs. 线程

分布式进程

正则表达式

常用内建模块

datetime

collections

argparse

base64

struct

hashlib

hmac

itertools

contextlib

urllib

XML

HTMLParser

常用第三方模块

Pillow

requests

chardet

psutil

venv

图形界面

海龟绘图

网络编程

TCP/IP简介

TCP编程

UDP编程

电子邮件

SMTP发送邮件

POP3收取邮件

访问数据库

使用SQLite

使用MySQL

使用SQLAlchemy

Web开发

HTTP协议简介

HTML简介

WSGI接口

使用Web框架

使用模板

异步IO

协程

asyncio

async/await

aiohttp

使用MicroPython

搭建开发环境

控制小车

遥控小车

遥控转向

实战

Day 1 - 搭建开发环境

Day 2 - 编写Web App骨架

Day 3 - 编写ORM

Day 4 - 编写Model

Day 5 - 编写Web框架

Day 6 - 编写配置文件

Day 7 - 编写MVC

Day 8 - 构建前端

Day 9 - 编写API

Day 10 - 用户注册和登录

Day 11 - 编写日志创建页

Day 12 - 编写日志列表页

Day 13 - 提升开发效率

Day 14 - 完成Web App

Day 15 - 部署Web App

Day 16 - 编写移动App

FAQ

期末总结

关注公众号不定期领红包:

加入知识星球社群:

关注微博获取实时动态:

collections

Last updated: ...

/

Reads: 10580681

Edit

collections是Python内建的一个集合模块,提供了许多有用的集合类。

namedtuple

我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:

>>> p = (1, 2)

但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。

定义一个class又小题大做了,这时,namedtuple就派上了用场:

>>> from collections import namedtuple

>>> Point = namedtuple('Point', ['x', 'y'])

>>> p = Point(1, 2)

>>> p.x

1

>>> p.y

2

namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。

这样一来,我们用namedtuple可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。

可以验证创建的Point对象是tuple的一种子类:

>>> isinstance(p, Point)

True

>>> isinstance(p, tuple)

True

类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

# namedtuple('名称', [属性list]):

Circle = namedtuple('Circle', ['x', 'y', 'r'])

deque

使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。

deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:

>>> from collections import deque

>>> q = deque(['a', 'b', 'c'])

>>> q.append('x')

>>> q.appendleft('y')

>>> q

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

deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。

defaultdict

使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:

>>> from collections import defaultdict

>>> dd = defaultdict(lambda: 'N/A')

>>> dd['key1'] = 'abc'

>>> dd['key1'] # key1存在

'abc'

>>> dd['key2'] # key2不存在,返回默认值

'N/A'

注意默认值是调用函数返回的,而函数在创建defaultdict对象时传入。

除了在Key不存在时返回默认值,defaultdict的其他行为跟dict是完全一样的。

OrderedDict

使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。

如果要保持Key的顺序,可以用OrderedDict:

>>> from collections import OrderedDict

>>> d = dict([('a', 1), ('b', 2), ('c', 3)])

>>> d # dict的Key是无序的

{'a': 1, 'c': 3, 'b': 2}

>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])

>>> od # OrderedDict的Key是有序的

OrderedDict([('a', 1), ('b', 2), ('c', 3)])

注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

>>> od = OrderedDict()

>>> od['z'] = 1

>>> od['y'] = 2

>>> od['x'] = 3

>>> list(od.keys()) # 按照插入的Key的顺序返回

['z', 'y', 'x']

OrderedDict可以实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最早添加的Key:

from collections import OrderedDict

class LastUpdatedOrderedDict(OrderedDict):

def __init__(self, capacity):

super(LastUpdatedOrderedDict, self).__init__()

self._capacity = capacity

def __setitem__(self, key, value):

containsKey = 1 if key in self else 0

if len(self) - containsKey >= self._capacity:

last = self.popitem(last=False)

print('remove:', last)

if containsKey:

del self[key]

print('set:', (key, value))

else:

print('add:', (key, value))

OrderedDict.__setitem__(self, key, value)

ChainMap

ChainMap可以把一组dict串起来并组成一个逻辑上的dict。ChainMap本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。

什么时候使用ChainMap最合适?举个例子:应用程序往往都需要传入参数,参数可以通过命令行传入,可以通过环境变量传入,还可以有默认参数。我们可以用ChainMap实现参数的优先级查找,即先查命令行参数,如果没有传入,再查环境变量,如果没有,就使用默认参数。

下面的代码演示了如何查找user和color这两个参数:

from collections import ChainMap

import os, argparse

# 构造缺省参数:

defaults = {

'color': 'red',

'user': 'guest'

}

# 构造命令行参数:

parser = argparse.ArgumentParser()

parser.add_argument('-u', '--user')

parser.add_argument('-c', '--color')

namespace = parser.parse_args()

command_line_args = { k: v for k, v in vars(namespace).items() if v }

# 组合成ChainMap:

combined = ChainMap(command_line_args, os.environ, defaults)

# 打印参数:

print('color=%s' % combined['color'])

print('user=%s' % combined['user'])

没有任何参数时,打印出默认参数:

$ python3 use_chainmap.py

color=red

user=guest

当传入命令行参数时,优先使用命令行参数:

$ python3 use_chainmap.py -u bob

color=red

user=bob

同时传入命令行参数和环境变量,命令行参数的优先级较高:

$ user=admin color=green python3 use_chainmap.py -u bob

color=green

user=bob

Counter

Counter是一个简单的计数器,例如,统计字符出现的个数:

>>> from collections import Counter

>>> c = Counter()

>>> for ch in 'programming':

... c[ch] = c[ch] + 1

...

>>> c

Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})

>>> c.update('hello') # 也可以一次性update

>>> c

Counter({'r': 2, 'o': 2, 'g': 2, 'm': 2, 'l': 2, 'p': 1, 'a': 1, 'i': 1, 'n': 1, 'h': 1, 'e': 1})

Counter实际上也是dict的一个子类,上面的结果可以看出每个字符出现的次数。

小结

collections模块提供了一些有用的集合类,可以根据需要选用。

参考源码

use_collections.py

Comments

Make a comment

Sign in to

make a comment

Index

Python教程

Python简介

安装Python

Python解释器

第一个Python程序

使用文本编辑器

Python代码运行助手

输入和输出

Python基础

数据类型和变量

字符串和编码

使用list和tuple

条件判断

模式匹配

循环

使用dict和set

函数

调用函数

定义函数

函数的参数

递归函数

高级特性

切片

迭代

列表生成式

生成器

迭代器

函数式编程

高阶函数

map/reduce

filter

sorted

返回函数

匿名函数

装饰器

偏函数

模块

使用模块

安装第三方模块

面向对象编程

类和实例

访问限制

继承和多态

获取对象信息

实例属性和类属性

面向对象高级编程

使用__slots__

使用@property

多重继承

定制类

使用枚举类

使用元类

错误、调试和测试

错误处理

调试

单元测试

文档测试

IO编程

文件读写

StringIO和BytesIO

操作文件和目录

序列化

进程和线程

多进程

多线程

ThreadLocal

进程 vs. 线程

分布式进程

正则表达式

常用内建模块

datetime

collections

argparse

base64

struct

hashlib

hmac

itertools

contextlib

urllib

XML

HTMLParser

常用第三方模块

Pillow

requests

chardet

psutil

venv

图形界面

海龟绘图

网络编程

TCP/IP简介

TCP编程

UDP编程

电子邮件

SMTP发送邮件

POP3收取邮件

访问数据库

使用SQLite

使用MySQL

使用SQLAlchemy

Web开发

HTTP协议简介

HTML简介

WSGI接口

使用Web框架

使用模板

异步IO

协程

asyncio

async/await

aiohttp

使用MicroPython

搭建开发环境

控制小车

遥控小车

遥控转向

实战

Day 1 - 搭建开发环境

Day 2 - 编写Web App骨架

Day 3 - 编写ORM

Day 4 - 编写Model

Day 5 - 编写Web框架

Day 6 - 编写配置文件

Day 7 - 编写MVC

Day 8 - 构建前端

Day 9 - 编写API

Day 10 - 用户注册和登录

Day 11 - 编写日志创建页

Day 12 - 编写日志列表页

Day 13 - 提升开发效率

Day 14 - 完成Web App

Day 15 - 部署Web App

Day 16 - 编写移动App

FAQ

期末总结

廖雪峰的官方网站

©Copyright 2019-2021

Powered by iTranswarp

Feedback

License

Python的collections原来这么好用! - 知乎

Python的collections原来这么好用! - 知乎切换模式写文章登录/注册Python的collections原来这么好用!Waynecollections是实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。为了让大家更好的认识,本文详细总结collections的相关知识,一起来学习吧!collections模块:实现了特定目标的容器,以提供Python标准内建容器 dict、list、set、tuple 的替代选择。Counter:字典的子类,提供了可哈希对象的计数功能。defaultdict:字典的子类,提供了一个工厂函数,为字典查询提供了默认值。OrderedDict:字典的子类,保留了他们被添加的顺序。namedtuple:创建命名元组子类的工厂函数。deque:类似列表容器,实现了在两端快速添加(append)和弹出(pop)。ChainMap:类似字典的容器类,将多个映射集合到一个视图里面。CounterCounter是一个dict子类,主要是用来对你访问的对象的频率进行计数。>>> import collections

>>> # 统计字符出现的次数

... collections.Counter('hello world')

Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})

>>> # 统计单词个数

... collections.Counter('hello world hello lucy'.split())

Counter({'hello': 2, 'world': 1, 'lucy': 1})

常用方法:elements():返回一个迭代器,每个元素重复计算的个数,如果一个元素的计数小于1,就会被忽略。most_common([n]):返回一个列表,提供n个访问频率最高的元素和计数subtract([iterable-or-mapping]):从迭代对象中减去元素,输入输出可以是0或者负数update([iterable-or-mapping]):从迭代对象计数元素或者从另一个 映射对象 (或计数器) 添加。>>> c = collections.Counter('hello world hello lucy'.split())

>>> c

Counter({'hello': 2, 'world': 1, 'lucy': 1})

>>> # 获取指定对象的访问次数,也可以使用get方法

... c['hello']

2

>>> # 查看元素

... list(c.elements())

['hello', 'hello', 'world', 'lucy']

>>> c1 = collections.Counter('hello world'.split())

>>> c2 = collections.Counter('hello lucy'.split())

>>> c1

Counter({'hello': 1, 'world': 1})

>>> c2

Counter({'hello': 1, 'lucy': 1})

>>> # 追加对象,+或者c1.update(c2)

... c1+c2

Counter({'hello': 2, 'world': 1, 'lucy': 1})

>>> # 减少对象,-或者c1.subtract(c2)

... c1-c2

Counter({'world': 1})

>>> # 清除

... c.clear()

>>> c

Counter()

defaultdict返回一个新的类似字典的对象。defaultdict 是内置 dict 类的子类。class collections.defaultdict([default_factory[, ...]])

>>> d = collections.defaultdict()

>>> d

defaultdict(None, {})

>>> e = collections.defaultdict(str)

>>> e

defaultdict(, {})

例子defaultdict的一个典型用法是使用其中一种内置类型(如str、int、list或dict等)作为默认工厂,这些内置类型在没有参数调用时返回空类型。>>> e = collections.defaultdict(str)

>>> e

defaultdict(, {})

>>> e['hello']

''

>>> e

defaultdict(, {'hello': ''})

>>> # 普通字典调用不存在的键时,报错

... e1 = {}

>>> e1['hello']

Traceback (most recent call last):

File "", line 1, in

KeyError: 'hello'

使用 int 作为 default_factory

>>> fruit = collections.defaultdict(int)

>>> fruit['apple'] = 2

>>> fruit

defaultdict(, {'apple': 2})

>>> fruit['banana'] # 没有对象时,返回0

0

>>> fruit

defaultdict(, {'apple': 2, 'banana': 0})

使用 list 作为 default_factory>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

>>> d = collections.defaultdict(list)

>>> for k,v in s:

... d[k].append(v)

...

>>> d

defaultdict(, {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]})

>>> d.items()

dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])])

>>> sorted(d.items())

[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

使用 dict 作为 default_factory

```python

>>> nums = collections.defaultdict(dict)

>>> nums[1] = {'one':1}

>>> nums

defaultdict(, {1: {'one': 1}})

>>> nums[2]

{}

>>> nums

defaultdict(, {1: {'one': 1}, 2: {}})

使用 set 作为 default_factory

```python

>>> types = collections.defaultdict(set)

>>> types['手机'].add('华为')

>>> types['手机'].add('小米')

>>> types['显示器'].add('AOC')

>>> types

defaultdict(, {'手机': {'华为', '小米'}, '显示器': {'AOC'}})

## OrderedDict

Python字典中的键的顺序是任意的,它们不受添加的顺序的控制。

collections.OrderedDict 类提供了保留他们添加顺序的字典对象。

```python

>>> o = collections.OrderedDict()

>>> o['k1'] = 'v1'

>>> o['k3'] = 'v3'

>>> o['k2'] = 'v2'

>>> o

OrderedDict([('k1', 'v1'), ('k3', 'v3'), ('k2', 'v2')])

如果在已经存在的 key 上添加新的值,将会保留原来的 key 的位置,然后覆盖 value 值。

```python

>>> o['k1'] = 666

>>> o

OrderedDict([('k1', 666), ('k3', 'v3'), ('k2', 'v2')])

>>> dict(o)

{'k1': 666, 'k3': 'v3', 'k2': 'v2'}

## namedtuple

三种定义命名元组的方法:第一个参数是命名元组的构造器(如下的:Person1,Person2,Person3)

```python

>>> P1 = collections.namedtuple('Person1',['name','age','height'])

>>> P2 = collections.namedtuple('Person2','name,age,height')

>>> P3 = collections.namedtuple('Person3','name age height')

实例化命名元组

```python

>>> lucy = P1('lucy',23,180)

>>> lucy

Person1(name='lucy', age=23, height=180)

>>> jack = P2('jack',20,190)

>>> jack

Person2(name='jack', age=20, height=190)

>>> lucy.name # 直接通过 实例名.属性 来调用

'lucy'

>>> lucy.age

23

dequecollections.deque 返回一个新的双向队列对象,从左到右初始化(用方法 append()),从 iterable(迭代对象)数据创建。如果 iterable 没有指定,新队列为空。collections.deque 队列支持线程安全,对于从两端添加(append)或者弹出(pop),复杂度O(1)。虽然 list 对象也支持类似操作,但是这里优化了定长操作(pop(0)、insert(0,v))的开销。如果 maxlen 没有指定或者是 None ,deque 可以增长到任意长度。否则,deque 就限定到指定最大长度。一旦限定长度的 deque 满了,当新项加入时,同样数量的项就从另一端弹出。支持的方法:append(x):添加x到右端。appendleft(x):添加x到左端。clear():清除所有元素,长度变为0。copy():创建一份浅拷贝。count(x):计算队列中个数等于x的元素。extend(iterable):在队列右侧添加iterable中的元素。extendleft(iterable):在队列左侧添加iterable中的元素,注:在左侧添加时,iterable参数的顺序将会反过来添加。index(x[,start[,stop]]):返回第 x 个元素(从 start 开始计算,在 stop 之前)。返回第一个匹配,如果没找到的话,抛出 ValueError 。insert(i,x):在位置 i 插入 x 。注:如果插入会导致一个限长deque超出长度 maxlen 的话,就抛出一个 IndexError 。pop():移除最右侧的元素。popleft():移除最左侧的元素。remove(value):移去找到的第一个 value。没有抛出ValueError。reverse():将deque逆序排列。返回 None 。maxlen:队列的最大长度,没有限定则为None。>>> d = collections.deque(maxlen=10)

>>> d

deque([], maxlen=10)

>>> d.extend('python')

>>> [i.upper() for i in d]

['P', 'Y', 'T', 'H', 'O', 'N']

>>> d.append('e')

>>> d.appendleft('f')

>>> d.appendleft('g')

>>> d.appendleft('h')

>>> d

deque(['h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n', 'e'], maxlen=10)

>>> d.appendleft('i')

>>> d

deque(['i', 'h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n'], maxlen=10)

>>> d.append('m')

>>> d

deque(['h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n', 'm'], maxlen=10)

## ChainMap

问题背景是我们有多个字典或者映射,想把它们合并成为一个单独的映射,有人说可以用update进行合并,这样做的问题就是新建了一个数据结构以致于当我们对原来的字典进行更改的时候不会同步。如果想建立一个同步的查询方法,可以使用 ChainMap。

可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询。简单使用:

```python

>>> d1 = {'apple':1,'banana':2}

>>> d2 = {'orange':2,'apple':3,'pike':1}

>>> combined1 = collections.ChainMap(d1,d2)

>>> combined2 = collections.ChainMap(d2,d1)

>>> combined1

ChainMap({'apple': 1, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1})

>>> combined2

ChainMap({'orange': 2, 'apple': 3, 'pike': 1}, {'apple': 1, 'banana': 2})

>>> for k,v in combined1.items():

... print(k,v)

...

orange 2

apple 1

pike 1

banana 2

>>> for k,v in combined2.items():

... print(k,v)

...

apple 3

banana 2

orange 2

pike 1

有一个注意点就是当对ChainMap进行修改的时候总是只会对第一个字典进行修改,如果第一个字典不存在该键,会添加。>>> d1 = {'apple':1,'banana':2}

>>> d2 = {'orange':2,'apple':3,'pike':1}

>>> c = collections.ChainMap(d1,d2)

>>> c

ChainMap({'apple': 1, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1})

>>> c['apple']

1

>>> c['apple'] = 2

>>> c

ChainMap({'apple': 2, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1})

>>> c['pike']

1

>>> c['pike'] = 3

>>> c

ChainMap({'apple': 2, 'banana': 2, 'pike': 3}, {'orange': 2, 'apple': 3, 'pike': 1})

从原理上面讲,ChainMap 实际上是把放入的字典存储在一个队列中,当进行字典的增加删除等操作只会在第一个字典上进行,当进行查找的时候会依次查找,new_child() 方法实质上是在列表的第一个元素前放入一个字典,默认是{},而 parents 是去掉了列表开头的元素。

```python

>>> a = collections.ChainMap()

>>> a['x'] = 1

>>> a

ChainMap({'x': 1})

>>> b = a.new_child()

>>> b

ChainMap({}, {'x': 1})

>>> b['x'] = 2

>>> b

ChainMap({'x': 2}, {'x': 1})

>>> b['y'] = 3

>>> b

ChainMap({'x': 2, 'y': 3}, {'x': 1})

>>> a

ChainMap({'x': 1})

>>> c = a.new_child()

>>> c

ChainMap({}, {'x': 1})

>>> c['x'] = 1

>>> c['y'] = 1

>>> c

ChainMap({'x': 1, 'y': 1}, {'x': 1})

>>> d = c.parents

>>> d

ChainMap({'x': 1})

>>> d is a

False

>>> d == a

True

>>> a = {'x':1,'z':3}

>>> b = {'y':2,'z':4}

>>> c = collections.ChainMap(a,b)

>>> c

ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})

>>> c.maps

[{'x': 1, 'z': 3}, {'y': 2, 'z': 4}]

>>> c.parents

ChainMap({'y': 2, 'z': 4})

>>> c.parents.maps

[{'y': 2, 'z': 4}]

>>> c.parents.parents

ChainMap({})

>>> c.parents.parents.parents

ChainMap({})

文章转自:Python程序员发布于 2021-02-28 21:48Python​赞同 14​​添加评论​分享​喜欢​收藏​申请

Python——详解collections工具库 - 知乎

Python——详解collections工具库 - 知乎首发于TechFlow切换模式写文章登录/注册Python——详解collections工具库梁唐​本文始发于个人公众号:TechFlow,原创不易,求个关注今天为大家介绍Python当中一个很好用也是很基础的工具库,叫做collections。collection在英文当中有容器的意思,所以顾名思义,这是一个容器的集合。这个库当中的容器很多,有一些不是很常用,本篇文章选择了其中最常用的几个,一起介绍给大家。defaultdictdefaultdict可以说是这个库当中使用最简单的一个,并且它的定义也很简单,我们从名称基本上就能看得出来。它解决的是我们使用dict当中最常见的问题,就是key为空的情况。在正常情况下,我们在dict中获取元素的时候,都需要考虑key为空的情况。如果不考虑这点,那么当我们获取了一个不存在的key,会导致系统抛出异常。我们当然可以在每次get之前写一个if判断,但是这很麻烦,比如:if key in dict:

return dict[key]

else:

return None当然,这是最笨的方法,dict当中为我们提供了带默认值的get方法。比如,我们可以写成:return dict.get(key, None)这样,当key不在dict当中存在的时候,会自动返回我们设置的默认值。这个省去了很多麻烦的判断,但是在一些特殊情况下仍然存在一点问题。举个例子,比如当key存在重复,我们希望将key相同的value存进一个list当中,而不是只保留一个。这种情况下写成代码就会比较复杂:data = [(1, 3), (2, 1), (1, 4), (2, 5), (3, 7)]

d = {}

for k, v in data:

if k in d:

d[k].append(v)

else:

d[k] = [v]由于dict的value是一个list,所以我们还是需要判断是否为空,不能直接使用默认值,间接操作当然可以,但是还是不够简单:for k, v in data:

cur = d.get(k, [])

cur.append(v)

d[k] = v这和使用if区别并不大,为了完美解决这个问题,我们可以使用collections当中的defaultdict:from collections import defaultdict

d = defaultdict(list)

for k, v in data:

d[k].append(v)使用defaultdict之后,如果key不存在,容器会自动返回我们预先设置的默认值。需要注意的是defaultdict传入的默认值可以是一个类型也可以是一个方法。如果我们传入int,那么默认值会被设置成int()的结果,也就是0,如果我们想要自定义或者修改,我们可以传入一个方法,比如:d = defaultdict(lambda: 3)

for k, v in data:

d[k] += vCounter这是一个非常常用和非常强大的工具,我们经常用到。在我们实际的编程当中,我们经常遇到一个问题,就是数数和排序。比如说我们在分析文本的时候,会得到一堆单词。其中可能有大量的长尾词,在整个文本当中可能只出现过寥寥几次。于是我们希望计算一下这些单词出现过的数量,只保留出现次数最高的若干个。这个需求让我们自己实现当然也不困难,我们完全可以创建一个dict,然后对这些单词一个一个遍历。原本我们还需要考虑单词之前没有出现过的情况,如果我们上面说的defaultdict,又要简单许多。但是我们还是少不了计数然后排序的步骤,如果使用Counter这个步骤会缩减成一行代码。举个例子:words = ['apple', 'apple', 'pear', 'watermelon', 'pear', 'peach']

from collections import Counter

counter = Counter(words)

>>> print(counter)

Counter({'apple': 2, 'pear': 2, 'watermelon': 1, 'peach': 1})我们直接将一个list传入Counter中作为参数,它会自动为我们替当中的每个元素计数。如果我们要筛选topK,也非常简单,它为我们提供了most_common方法,我们只需要传入需要求的K即可:counter.most_common(1)

[('apple', 2)]除此之外,它的构造函数还接收dict类型。我们可以直接通过一个value是int类型的dict来初始化一个Counter,比如:c = Counter({'apple': 5, 'pear': 4})

c = Counter(apple=4, pear=3)并且,它还支持加减法的操作,比如我们可以将两个Counter相加,它会自动将两个Counter合并,相同的key对应的value累加。相减也是同理,会将能对应的value做减法,被减的key对应不上的会保留,而减数中对应不上的key则会被丢弃。并且需要注意,Counter支持value为负数。deque我们都知道queue是队列,deque也是队列,不过稍稍特殊一些,是双端队列。对于queue来说,只允许在队尾插入元素,在队首弹出元素。而deque既然称为双端队列,那么说明它的队首和队尾都支持元素的插入和弹出。相比于普通的队列,要更加灵活一些。除了常用的clear、copy、count、extend等api之外,deque当中最常用也是最核心的api还有append、pop、appendleft和popleft。从名字上我们就看得出来,append和pop和list的append和pop一样,而appendleft和popleft则是在队列左侧,也就是头部进行pop和append的操作。非常容易理解。在日常的使用当中,真正用到双端队列的算法其实不太多。大多数情况下我们使用deque主要有两个原因,第一个原因是deque收到GIL的管理,它是线程安全的。而list则没有GIL锁,因此不是线程安全的。也就是说在并发场景下,list可能会导致一致性问题,而deque不会。另一个原因是deque支持固定长度,当长度满了之后,当我们继续append时,它会自动弹出最早插入的数据。比如说当我们拥有海量的数据,我们不知道它的数量,但是想要保留最后出现的指定数量的数据的时候,就可以使用deque。from collections import deque

dque = deque(maxlen=10)

# 假设我们想要从文件当中获取最后10条数据

for i in f.read():

dque.append(i)namedtuplenamedtuple很特殊,它涉及到元编程的概念。简单介绍一下元编程的概念,我们不做过多的深入。简而言之,就是在常见的面向对象当中。我们都是定义类,然后通过类的构造函数来创建实例。而元编程指的是我们定义元类,根据元类创建出来的并不是一个实例,而是一个类。如果用模具和成品来分别比喻类和实例的话,元类相当于是模具的模具。namedtuple是一个非常简单的元类,通过它我们可以非常方便地定义我们想要的类。它的用法很简单,我们直接来看例子。比如如果我们想要定义一个学生类,这个类当中有name、score、age这三个字段,那么这个类会写成:class Student:

def __init__(self, name=None, score=None, age=None):

self.name = name

self.score = score

self.age = age这还只是粗略的写法,如果考虑规范,还需要定义property等注解,又需要很多代码。如果我们使用namedtuple可以简化这个工作,我们来看代码:from collections import namedtuple

# 这个是类,columns也可以写成'name score age',即用空格分开

Student = namedtuple('Student', ['name', 'score', 'age'])

# 这个是实例

student = Student(name='xiaoming', score=99, age=10)

print(student.name)通过使用namedtuple,我们只需要一行就定义了一个类,但是这样定义的类是没有缺失值的,但是namedtuple很强大,我们可以通过传入defaults参数来定义缺失值。Student = namedtuple('Student', ['name', 'score', 'age'], defaults=(0, 0))可以注意到,虽然我们定义了三个字段,但是我们只设置了两个缺失值。在这种情况下,namedtuple会自动将缺失值匹配上score和age两个字段。因为在Python的规范当中,必选参数一定在可选参数前面。所以nuamdtuple会自动右对齐。细数一下,我们今天的文章当中介绍了defaultdict、Counter、deque和namedtuple这四种数据结构的用法。除了这四个之外,collections库当中还有一些其他的工具类,只是我们用的频率稍稍低一些,加上由于篇幅的原因,这里就不多做赘述了。感兴趣的同学可以自行查看相关的api和文档。今天的文章就是这些,如果觉得有所收获,请顺手扫码点个关注吧,你们的举手之劳对我来说很重要。发布于 2020-03-03 08:44PythonPython 开发Python教程​赞同 62​​8 条评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录TechFlow简单文章,复

Python's collections: A Buffet of Specialized Data Types – Real Python

Python's collections: A Buffet of Specialized Data Types – Real Python

Start Here

Learn Python

Python Tutorials →In-depth articles and video courses

Learning Paths →Guided study plans for accelerated learning

Quizzes →Check your learning progress

Browse Topics →Focus on a specific area or skill level

Community Chat →Learn with other Pythonistas

Office Hours →Live Q&A calls with Python experts

Podcast →Hear what’s new in the world of Python

Books →Round out your knowledge and learn offline

Unlock All Content →

More

Learner Stories

Python Newsletter

Python Job Board

Meet the Team

Become a Tutorial Writer

Become a Video Instructor

Search

/

Join

Sign‑In

— FREE Email Series —

Python Tricks

Get Python Tricks »

No spam. Unsubscribe any time.

Browse Topics

Guided Learning Paths

Basics

Intermediate

Advanced

api

best-practices

career

community

databases

data-science

data-structures

data-viz

devops

django

docker

editors

flask

front-end

gamedev

gui

machine-learning

numpy

projects

python

testing

tools

web-dev

web-scraping

Table of Contents

Getting Started With Python’s collections

Improving Code Readability: namedtuple()

Building Efficient Queues and Stacks: deque

Handling Missing Keys: defaultdict

Keeping Your Dictionaries Ordered: OrderedDict

Counting Objects in One Go: Counter

Chaining Dictionaries Together: ChainMap

Customizing Built-Ins: UserString, UserList, and UserDict

Conclusion

Mark as Completed

Share

Share

Email

Python's collections: A Buffet of Specialized Data Types

by Leodanis Pozo Ramos

data-structures

intermediate

python

Mark as Completed

Share

Share

Email

Table of Contents

Getting Started With Python’s collections

Improving Code Readability: namedtuple()

Building Efficient Queues and Stacks: deque

Handling Missing Keys: defaultdict

Keeping Your Dictionaries Ordered: OrderedDict

Counting Objects in One Go: Counter

Chaining Dictionaries Together: ChainMap

Customizing Built-Ins: UserString, UserList, and UserDict

Conclusion

Remove ads

Python’s collections module provides a rich set of specialized container data types carefully designed to approach specific programming problems in a Pythonic and efficient way. The module also provides wrapper classes that make it safer to create custom classes that behave similar to the built-in types dict, list, and str.

Learning about the data types and classes in collections will allow you to grow your programming tool kit with a valuable set of reliable and efficient tools.

In this tutorial, you’ll learn how to:

Write readable and explicit code with namedtuple

Build efficient queues and stacks with deque

Count objects quickly with Counter

Handle missing dictionary keys with defaultdict

Guarantee the insertion order of keys with OrderedDict

Manage multiple dictionaries as a single unit with ChainMap

To better understand the data types and classes in collections, you should know the basics of working with Python’s built-in data types, such as lists, tuples, and dictionaries. Additionally, the last part of the article requires some basic knowledge about object-oriented programming in Python.

Free Download: Get a sample chapter from Python Tricks: The Book that shows you Python’s best practices with simple examples you can apply instantly to write more beautiful + Pythonic code.

Getting Started With Python’s collections

Back in Python 2.4, Raymond Hettinger contributed a new module called collections to the standard library. The goal was to provide various specialized collection data types to approach specific programming problems.

At that time, collections only included one data structure, deque, which was specially designed as a double-ended queue that supports efficient append and pop operations on either end of the sequence. From this point on, several modules in the standard library took advantage of deque to improve the performance of their classes and structures. Some outstanding examples are queue and threading.

With time, a handful of specialized container data types populated the module:

Data type

Python version

Description

deque

2.4

A sequence-like collection that supports efficient addition and removal of items from either end of the sequence

defaultdict

2.5

A dictionary subclass for constructing default values for missing keys and automatically adding them to the dictionary

namedtuple()

2.6

A factory function for creating subclasses of tuple that provides named fields that allow accessing items by name while keeping the ability to access items by index

OrderedDict

2.7, 3.1

A dictionary subclass that keeps the key-value pairs ordered according to when the keys are inserted

Counter

2.7, 3.1

A dictionary subclass that supports convenient counting of unique items in a sequence or iterable

ChainMap

3.3

A dictionary-like class that allows treating a number of mappings as a single dictionary object

Besides these specialized data types, collections also provides three base classes that facilitate the creations of custom lists, dictionaries, and strings:

Class

Description

UserDict

A wrapper class around a dictionary object that facilitates subclassing dict

UserList

A wrapper class around a list object that facilitates subclassing list

UserString

A wrapper class around a string object that facilitates subclassing string

The need for these wrapper classes was partially eclipsed by the ability to subclass the corresponding standard built-in data types. However, sometimes using these classes is safer and less error-prone than using standard data types.

With this brief introduction to collections and the specific use cases that the data structures and classes in this module can solve, it’s time to take a closer look at them. Before that, it’s important to point out that this tutorial is an introduction to collections as a whole. In most of the following sections, you’ll find a blue alert box that’ll guide you to a dedicated article on the class or function at hand.

Remove adsImproving Code Readability: namedtuple()

Python’s namedtuple() is a factory function that allows you to create tuple subclasses with named fields. These fields give you direct access to the values in a given named tuple using the dot notation, like in obj.attr.

The need for this feature arose because using indices to access the values in a regular tuple is annoying, difficult to read, and error-prone. This is especially true if the tuple you’re working with has several items and is constructed far away from where you’re using it.

Note: Check out Write Pythonic and Clean Code With namedtuple for a deeper dive into how to use namedtuple in Python.

A tuple subclass with named fields that developers can access with the dot notation seemed like a desirable feature back in Python 2.6. That’s the origin of namedtuple(). The tuple subclasses you can build with this function are a big win in code readability if you compare them with regular tuples.

To put the code readability problem in perspective, consider divmod(). This built-in function takes two (non-complex) numbers and returns a tuple with the quotient and remainder that result from the integer division of the input values:

Python

>>> divmod(12, 5)

(2, 2)

It works nicely. However, is this result readable? Can you tell what the meaning of each number in the output is? Fortunately, Python offers a way to improve this. You can code a custom version of divmod() with an explicit result using namedtuple:

Python

>>> from collections import namedtuple

>>> def custom_divmod(x, y):

... DivMod = namedtuple("DivMod", "quotient remainder")

... return DivMod(*divmod(x, y))

...

>>> result = custom_divmod(12, 5)

>>> result

DivMod(quotient=2, remainder=2)

>>> result.quotient

2

>>> result.remainder

2

Now you know the meaning of each value in the result. You can also access each independent value using the dot notation and a descriptive field name.

To create new tuple subclass using namedtuple(), you need two required arguments:

typename is the name of the class you’re creating. It must be a string with a valid Python identifier.

field_names is the list of field names you’ll use to access the items in the resulting tuple. It can be:

An iterable of strings, such as ["field1", "field2", ..., "fieldN"]

A string with whitespace-separated field names, such as "field1 field2 ... fieldN"

A string with comma-separated field names, such as "field1, field2, ..., fieldN"

For example, here are different ways to create a sample 2D Point with two coordinates (x and y) using namedtuple():

Python

>>> from collections import namedtuple

>>> # Use a list of strings as field names

>>> Point = namedtuple("Point", ["x", "y"])

>>> point = Point(2, 4)

>>> point

Point(x=2, y=4)

>>> # Access the coordinates

>>> point.x

2

>>> point.y

4

>>> point[0]

2

>>> # Use a generator expression as field names

>>> Point = namedtuple("Point", (field for field in "xy"))

>>> Point(2, 4)

Point(x=2, y=4)

>>> # Use a string with comma-separated field names

>>> Point = namedtuple("Point", "x, y")

>>> Point(2, 4)

Point(x=2, y=4)

>>> # Use a string with space-separated field names

>>> Point = namedtuple("Point", "x y")

>>> Point(2, 4)

Point(x=2, y=4)

In these examples, you first create Point using a list of field names. Then you instantiate Point to make a point object. Note that you can access x and y by field name and also by index.

The remaining examples show how to create an equivalent named tuple with a string of comma-separated field names, a generator expression, and a string of space-separated field names.

Named tuples also provide a bunch of cool features that allow you to define default values for your fields, create a dictionary from a given named tuple, replace the value of a given field, and more:

Python

>>> from collections import namedtuple

>>> # Define default values for fields

>>> Person = namedtuple("Person", "name job", defaults=["Python Developer"])

>>> person = Person("Jane")

>>> person

Person(name='Jane', job='Python Developer')

>>> # Create a dictionary from a named tuple

>>> person._asdict()

{'name': 'Jane', 'job': 'Python Developer'}

>>> # Replace the value of a field

>>> person = person._replace(job="Web Developer")

>>> person

Person(name='Jane', job='Web Developer')

Here, you first create a Person class using namedtuple(). This time, you use an optional argument called defaults that accepts a sequence of default values for the tuple’s fields. Note that namedtuple() applies the default values to the rightmost fields.

In the second example, you create a dictionary from an existing named tuple using ._asdict(). This method returns a new dictionary that uses the field names as keys.

Finally, you use ._replace() to replace the original value of job. This method doesn’t update the tuple in place but returns a new named tuple with the new value stored in the corresponding field. Do you have an idea of why ._replace() returns a new named tuple?

Remove adsBuilding Efficient Queues and Stacks: deque

Python’s deque was the first data structure in collections. This sequence-like data type is a generalization of stacks and queues designed to support memory-efficient and fast append and pop operations on both ends of the data structure.

Note: The word deque is pronounced “deck” and stands for double-ended queue.

In Python, append and pop operations on the beginning or left side of list objects are inefficient, with O(n) time complexity. These operations are especially expensive if you’re working with large lists because Python has to move all the items to the right to insert new items at the beginning of the list.

On the other hand, append and pop operations on the right side of a list are normally efficient (O(1)) except for those cases in which Python needs to reallocate memory to grow the underlying list for accepting new items.

Python’s deque was created to overcome this problem. Append and pop operations on both sides of a deque object are stable and equally efficient because deques are implemented as a doubly linked list. That’s why deques are particularly useful for creating stacks and queues.

Take a queue as an example. It manages items in a First-In/First-Out (FIFO) fashion. It works as a pipe, where you push in new items at one end of the pipe and pop old items out from the other end. Adding an item to the end of a queue is known as an enqueue operation. Removing an item from the front or beginning of a queue is called dequeue.

Note: Check out Python’s deque: Implement Efficient Queues and Stacks for a thorough exploration into using deque in your Python code.

Now say you’re modeling a queue of people waiting to buy tickets to a movie. You can do that with a deque. Every time a new person arrives, you enqueue them. When the person at the front of the queue gets their tickets, you dequeue them.

Here’s how you can emulate the process using a deque object:

Python

>>> from collections import deque

>>> ticket_queue = deque()

>>> ticket_queue

deque([])

>>> # People arrive to the queue

>>> ticket_queue.append("Jane")

>>> ticket_queue.append("John")

>>> ticket_queue.append("Linda")

>>> ticket_queue

deque(['Jane', 'John', 'Linda'])

>>> # People bought their tickets

>>> ticket_queue.popleft()

'Jane'

>>> ticket_queue.popleft()

'John'

>>> ticket_queue.popleft()

'Linda'

>>> # No people on the queue

>>> ticket_queue.popleft()

Traceback (most recent call last):

File "", line 1, in

IndexError: pop from an empty deque

Here, you first create an empty deque object to represent the queue of people. To enqueue a person, you can use .append(), which adds items to the right end of a deque. To dequeue a person, you use .popleft(), which removes and returns items on the left end of a deque.

Note: In the Python standard library, you’ll find queue. This module implements multi-producer, multi-consumer queues useful for exchanging information between multiple threads safely.

The deque initializer takes two optional arguments:

iterable holds an iterable that serves as an initializer.

maxlen holds an integer number that specifies the maximum length of the deque.

If you don’t provide an iterable, then you get an empty deque. If you supply a value to maxlen, then your deque will only store up to maxlen items.

Having a maxlen is a handy feature. For example, say you need to implement a list of recent files in one of your applications. In that case, you can do the following:

Python

>>> from collections import deque

>>> recent_files = deque(["core.py", "README.md", "__init__.py"], maxlen=3)

>>> recent_files.appendleft("database.py")

>>> recent_files

deque(['database.py', 'core.py', 'README.md'], maxlen=3)

>>> recent_files.appendleft("requirements.txt")

>>> recent_files

deque(['requirements.txt', 'database.py', 'core.py'], maxlen=3)

Once the deque reaches its maximum size (three files in this case), adding a new file on an end of the deque automatically discards the file at the opposite end. If you don’t supply a value to maxlen, then the deque can grow to an arbitrary number of items.

So far, you’ve learned the basics of deques, including how to create them and how to append and pop items from both ends of a given deque. Deques provide some additional features with a list-like interface. Here are some of them:

Python

>>> from collections import deque

>>> # Use different iterables to create deques

>>> deque((1, 2, 3, 4))

deque([1, 2, 3, 4])

>>> deque([1, 2, 3, 4])

deque([1, 2, 3, 4])

>>> deque("abcd")

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

>>> # Unlike lists, deque doesn't support .pop() with arbitrary indices

>>> deque("abcd").pop(2)

Traceback (most recent call last):

File "", line 1, in

TypeError: pop() takes no arguments (1 given)

>>> # Extend an existing deque

>>> numbers = deque([1, 2])

>>> numbers.extend([3, 4, 5])

>>> numbers

deque([1, 2, 3, 4, 5])

>>> numbers.extendleft([-1, -2, -3, -4, -5])

>>> numbers

deque([-5, -4, -3, -2, -1, 1, 2, 3, 4, 5])

>>> # Insert an item at a given position

>>> numbers.insert(5, 0)

>>> numbers

deque([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5])

In these examples, you first create deques using different types of iterables to initialize them. One difference between deque and list is that deque.pop() doesn’t support popping the item at a given index.

Note that deque provides sister methods for .append(), .pop(), and .extend() with the suffix left to indicate that they perform the corresponding operation on the left end of the underlying deque.

Deques also support sequence operations:

Method

Description

.clear()

Remove all the elements from a deque

.copy()

Create a shallow copy of a deque

.count(x)

Count the number of deque elements equal to x

.remove(value)

Remove the first occurrence of value

Another interesting feature of deques is the ability to rotate their elements using .rotate():

Python

>>> from collections import deque

>>> ordinals = deque(["first", "second", "third"])

>>> ordinals.rotate()

>>> ordinals

deque(['third', 'first', 'second'])

>>> ordinals.rotate(2)

>>> ordinals

deque(['first', 'second', 'third'])

>>> ordinals.rotate(-2)

>>> ordinals

deque(['third', 'first', 'second'])

>>> ordinals.rotate(-1)

>>> ordinals

deque(['first', 'second', 'third'])

This method rotates the deque n steps to the right. The default value of n is 1. If you provide a negative value to n, then the rotation is to the left.

Finally, you can use indices to access the elements in a deque, but you can’t slice a deque:

Python

>>> from collections import deque

>>> ordinals = deque(["first", "second", "third"])

>>> ordinals[1]

'second'

>>> ordinals[0:2]

Traceback (most recent call last):

File "", line 1, in

TypeError: sequence index must be integer, not 'slice'

Deques support indexing but, interestingly, they don’t support slicing. When you try to retrieve a slice from an existing deque, you get a TypeError. This is because performing a slice operation on a linked list would be inefficient, so the operation isn’t available.

Remove adsHandling Missing Keys: defaultdict

A common problem you’ll face when you’re working with dictionaries in Python is how to handle missing keys. If you try to access a key that doesn’t exist in a given dictionary, then you get a KeyError:

Python

>>> favorites = {"pet": "dog", "color": "blue", "language": "Python"}

>>> favorites["fruit"]

Traceback (most recent call last):

File "", line 1, in

KeyError: 'fruit'

There are a few approaches to work around this issue. For example, you can use .setdefault(). This method takes a key as an argument. If the key exists in the dictionary, then it returns the corresponding value. Otherwise, the method inserts the key, assigns it a default value, and returns that value:

Python

>>> favorites = {"pet": "dog", "color": "blue", "language": "Python"}

>>> favorites.setdefault("fruit", "apple")

'apple'

>>> favorites

{'pet': 'dog', 'color': 'blue', 'language': 'Python', 'fruit': 'apple'}

>>> favorites.setdefault("pet", "cat")

'dog'

>>> favorites

{'pet': 'dog', 'color': 'blue', 'language': 'Python', 'fruit': 'apple'}

In this example, you use .setdefault() to generate a default value for fruit. Since this key doesn’t exist in favorites, .setdefault() creates it and assigns it the value of apple. If you call .setdefault() with an existent key, then the call won’t affect the dictionary and your key will hold the original value instead of the default value.

You can also use .get() to return a suitable default value if a given key is missing:

Python

>>> favorites = {"pet": "dog", "color": "blue", "language": "Python"}

>>> favorites.get("fruit", "apple")

'apple'

>>> favorites

{'pet': 'dog', 'color': 'blue', 'language': 'Python'}

Here, .get() returns apple because the key is missing in the underlying dictionary. However, .get() doesn’t create the new key for you.

Since handling missing keys in dictionaries is a common need, Python’s collections also provides a tool for that. The defaultdict type is a subclass of dict designed to help you out with missing keys.

Note: Check out Using the Python defaultdict Type for Handling Missing Keys for a deeper dive into how to use Python’s defaultdict.

The constructor of defaultdict takes a function object as its first argument. When you access a key that doesn’t exist, defaultdict automatically calls that function without arguments to create a suitable default value for the key at hand.

To provide its functionality, defaultdict stores the input function in .default_factory and then overrides .__missing__() to automatically call the function and generate a default value when you access any missing keys.

You can use any callable to initialize your defaultdict objects. For example, with int() you can create a suitable counter to count different objects:

Python

>>> from collections import defaultdict

>>> counter = defaultdict(int)

>>> counter

defaultdict(, {})

>>> counter["dogs"]

0

>>> counter

defaultdict(, {'dogs': 0})

>>> counter["dogs"] += 1

>>> counter["dogs"] += 1

>>> counter["dogs"] += 1

>>> counter["cats"] += 1

>>> counter["cats"] += 1

>>> counter

defaultdict(, {'dogs': 3, 'cats': 2})

In this example, you create an empty defaultdict with int() as its first argument. When you access a key that doesn’t exist, the dictionary automatically calls int(), which returns 0 as the default value for the key at hand. This kind of defaultdict object is quite useful when it comes to counting things in Python.

Another common use case of defaultdict is to group things. In this case, the handy factory function is list():

Python

>>> from collections import defaultdict

>>> pets = [

... ("dog", "Affenpinscher"),

... ("dog", "Terrier"),

... ("dog", "Boxer"),

... ("cat", "Abyssinian"),

... ("cat", "Birman"),

... ]

>>> group_pets = defaultdict(list)

>>> for pet, breed in pets:

... group_pets[pet].append(breed)

...

>>> for pet, breeds in group_pets.items():

... print(pet, "->", breeds)

...

dog -> ['Affenpinscher', 'Terrier', 'Boxer']

cat -> ['Abyssinian', 'Birman']

In this example, you have raw data about pets and their breed, and you need to group them by pet. To do this, you use list() as .default_factory when you create the defaultdict instance. This enables your dictionary to automatically create an empty list ([]) as the default value for every missing key you access. Then you use that list to store the breeds of your pets.

Finally, you should note that since defaultdict is a subclass of dict, it provides the same interface. This means that you can use your defaultdict objects as you would use a regular dictionary.

Remove adsKeeping Your Dictionaries Ordered: OrderedDict

Sometimes you need your dictionaries to remember the order in which key-value pairs are inserted. Python’s regular dictionaries were unordered data structures for years. So, back in 2008, PEP 372 introduced the idea of adding a new dictionary class to collections.

The new class would remember the order of items based on the moment in which keys were inserted. That was the origin of OrderedDict.

OrderedDict was introduced in Python 3.1. Its application programming interface (API) is substantially the same as dict. However, OrderedDict iterates over keys and values in the same order keys were first inserted into the dictionary. If you assign a new value to an existing key, then the order of the key-value pair remains unchanged. If an entry is deleted and reinserted, then it’ll be moved to the end of the dictionary.

Note: Check out OrderedDict vs dict in Python: The Right Tool for the Job for a deeper dive into Python’s OrderedDict and why you should consider using it.

There are several ways to create OrderedDict objects. Most of them are identical to how you create a regular dictionary. For example, you can create an empty ordered dictionary by instantiating the class without arguments and then insert key-value pairs as needed:

Python

>>> from collections import OrderedDict

>>> life_stages = OrderedDict()

>>> life_stages["childhood"] = "0-9"

>>> life_stages["adolescence"] = "9-18"

>>> life_stages["adulthood"] = "18-65"

>>> life_stages["old"] = "+65"

>>> for stage, years in life_stages.items():

... print(stage, "->", years)

...

childhood -> 0-9

adolescence -> 9-18

adulthood -> 18-65

old -> +65

In this example, you create an empty ordered dictionary by instantiating OrderedDict without arguments. Next, you add key-value pairs to the dictionary as you would with a regular dictionary.

When you iterate through the dictionary, life_stages, you get the key-value pairs in the same order you inserted them into the dictionary. Guaranteeing the order of items is the main problem that OrderedDict solves.

Python 3.6 introduced a new implementation of dict. This implementation provides an unexpected new feature: now regular dictionaries keep their items in the same order they’re first inserted.

Initially, the feature was considered an implementation detail, and the documentation advised not to rely on it. However, since Python 3.7, the feature is officially part of the language specification. So, what’s the point of using OrderedDict?

There are some features of OrderedDict that still make it valuable:

Intent communication: With OrderedDict, your code will make it clear that the order of items in the dictionary is important. You’re clearly communicating that your code needs or relies on the order of items in the underlying dictionary.

Control over the order of items: With OrderedDict, you have access to .move_to_end(), which is a method that allows you to manipulate the order of items in your dictionary. You’ll also have an enhanced variation of .popitem() that allows removing items from either end of the underlying dictionary.

Equality test behavior: With OrderedDict, equality tests between dictionaries take the order of items into account. So, if you have two ordered dictionaries with the same group of items but in a different order, then your dictionaries will be considered non-equal.

There is at least one more reason for using OrderedDict: backward compatibility. Relying on regular dict objects to preserve the order of items will break your code in environments that run versions of Python older than 3.6.

Okay, now it’s time to see some of these cool features of OrderedDict in action:

Python

>>> from collections import OrderedDict

>>> letters = OrderedDict(b=2, d=4, a=1, c=3)

>>> letters

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

>>> # Move b to the right end

>>> letters.move_to_end("b")

>>> letters

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

>>> # Move b to the left end

>>> letters.move_to_end("b", last=False)

>>> letters

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

>>> # Sort letters by key

>>> for key in sorted(letters):

... letters.move_to_end(key)

...

>>> letters

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

In these examples, you use .move_to_end() to move items around and reorder letters. Note that .move_to_end() accepts an optional argument called last that allows you to control which end of the dictionary you want to move the items to. This method is quite handy when you need to sort the items in your dictionaries or when you need to manipulate their order in any way.

Another important difference between OrderedDict and a regular dictionary is how they compare for equality:

Python

>>> from collections import OrderedDict

>>> # Regular dictionaries compare the content only

>>> letters_0 = dict(a=1, b=2, c=3, d=4)

>>> letters_1 = dict(b=2, a=1, d=4, c=3)

>>> letters_0 == letters_1

True

>>> # Ordered dictionaries compare content and order

>>> letters_0 = OrderedDict(a=1, b=2, c=3, d=4)

>>> letters_1 = OrderedDict(b=2, a=1, d=4, c=3)

>>> letters_0 == letters_1

False

>>> letters_2 = OrderedDict(a=1, b=2, c=3, d=4)

>>> letters_0 == letters_2

True

Here, letters_1 has a different item order from letters_0. When you use regular dictionaries, this difference doesn’t matter and both dictionaries compare equal. On the other hand, when you use ordered dictionaries, letters_0 and letters_1 aren’t equal. This is because equality tests between ordered dictionaries consider the content and also the order of items.

Remove adsCounting Objects in One Go: Counter

Counting objects is a common operation in programming. Say you need to count how many times a given item appears in a list or iterable. If your list is short, then counting its items can be straightforward and quick. If you have a long list, then counting the items will be more challenging.

To count objects, you typically use a counter, or an integer variable with an initial value of zero. Then you increment the counter to reflect the number of times a given object occurs.

In Python, you can use a dictionary to count several different objects at once. In this case, the keys will store individual objects, and the values will hold the number of repetitions of a given object, or the object’s count.

Here’s an example that counts the letters in the word "mississippi" with a regular dictionary and a for loop:

Python

>>> word = "mississippi"

>>> counter = {}

>>> for letter in word:

... if letter not in counter:

... counter[letter] = 0

... counter[letter] += 1

...

>>> counter

{'m': 1, 'i': 4, 's': 4, 'p': 2}

The loop iterates over the letters in word. The conditional statement checks if the letters aren’t already in the dictionary and initializes the letter’s count to zero accordingly. The final step is to increment the letter’s count as the loop goes.

As you already know, defaultdict objects are convenient when it comes to counting things because you don’t need to check if the key exists. The dictionary guarantees appropriate default values for any missing keys:

Python

>>> from collections import defaultdict

>>> counter = defaultdict(int)

>>> for letter in "mississippi":

... counter[letter] += 1

...

>>> counter

defaultdict(, {'m': 1, 'i': 4, 's': 4, 'p': 2})

In this example, you create a defaultdict object and initialize it using int(). With int() as a factory function, the underlying default dictionary automatically creates missing keys and conveniently initializes them to zero. Then you increment the value of the current key to compute the final count of the letter in "mississippi".

Just like with other common programming problems, Python also has an efficient tool for approaching the counting problem. In collections, you’ll find Counter, which is a dict subclass specially designed for counting objects.

Here’s how you can write the "mississippi" example using Counter:

Python

>>> from collections import Counter

>>> Counter("mississippi")

Counter({'i': 4, 's': 4, 'p': 2, 'm': 1})

Wow! That was quick! A single line of code and you’re done. In this example, Counter iterates over "mississippi", producing a dictionary with the letters as keys and their frequency as values.

Note: Check out Python’s Counter: The Pythonic Way to Count Objects for a deeper dive into Counter and how to use it for counting objects efficiently.

There are a few different ways to instantiate Counter. You can use lists, tuples, or any iterables with repeated objects. The only restriction is that your objects need to be hashable:

Python

>>> from collections import Counter

>>> Counter([1, 1, 2, 3, 3, 3, 4])

Counter({3: 3, 1: 2, 2: 1, 4: 1})

>>> Counter(([1], [1]))

Traceback (most recent call last):

...

TypeError: unhashable type: 'list'

Integer numbers are hashable, so Counter works correctly. On the other hand, lists aren’t hashable, so Counter fails with a TypeError.

Being hashable means that your objects must have a hash value that never changes during their lifetime. This is a requirement because these objects will work as dictionary keys. In Python, immutable objects are also hashable.

Note: In Counter, a highly optimized C function provides the counting functionality. If this function isn’t available for some reason, then the class uses an equivalent but less efficient Python function.

Since Counter is a subclass of dict, their interfaces are mostly the same. However, there are some subtle differences. The first difference is that Counter doesn’t implement .fromkeys(). This avoids inconsistencies, such as Counter.fromkeys("abbbc", 2), in which every letter would have an initial count of 2 regardless of the real count it has in the input iterable.

The second difference is that .update() doesn’t replace the count (value) of an existing object (key) with a new count. It adds both counts together:

Python

>>> from collections import Counter

>>> letters = Counter("mississippi")

>>> letters

Counter({'i': 4, 's': 4, 'p': 2, 'm': 1})

>>> # Update the counts of m and i

>>> letters.update(m=3, i=4)

>>> letters

Counter({'i': 8, 'm': 4, 's': 4, 'p': 2})

>>> # Add a new key-count pair

>>> letters.update({"a": 2})

>>> letters

Counter({'i': 8, 'm': 4, 's': 4, 'p': 2, 'a': 2})

>>> # Update with another counter

>>> letters.update(Counter(["s", "s", "p"]))

>>> letters

Counter({'i': 8, 's': 6, 'm': 4, 'p': 3, 'a': 2})

Here, you update the count for m and i. Now those letters hold the sum of their initial count plus the value you passed to them through .update(). If you use a key that isn’t present in the original counter, then .update() creates the new key with the corresponding value. Finally, .update() accepts iterables, mappings, keyword arguments, and also other counters.

Note: Since Counter is a subclass of dict, there are no restrictions on the objects you can store in the keys and values of your counters. The keys can store any hashable objects, whereas the values can store any objects. However, to logically work as counters, the values should be integer numbers representing counts.

Another difference between Counter and dict is that accessing a missing key returns 0 instead of raising a KeyError:

Python

>>> from collections import Counter

>>> letters = Counter("mississippi")

>>> letters["a"]

0

This behavior signals that the count of an object that doesn’t exist in the counter is zero. In this example, the letter "a" isn’t in the original word, so its count is 0.

In Python, Counter is also useful to emulate a multiset or bag. Multisets are similar to sets, but they allow multiple instances of a given element. The number of instances of an element is known as its multiplicity. For example, you can have a multiset like {1, 1, 2, 3, 3, 3, 4, 4}.

When you use Counter to emulate multisets, the keys represent the elements, and the values represent their respective multiplicity:

Python

>>> from collections import Counter

>>> multiset = Counter([1, 1, 2, 3, 3, 3, 4, 4])

>>> multiset

Counter({1: 2, 2: 1, 3: 3, 4: 2})

>>> multiset.keys() == {1, 2, 3, 4}

True

Here, the keys of multiset are equivalent to a Python set. The values hold the multiplicity of each element in the set.

Python’ Counter provides a few additional features that help you work with them as multisets. For example, you can initialize your counters with a mapping of elements and their multiplicity. You can also perform math operations on the elements’ multiplicity and more.

Say you’re working at the local pet shelter. You have a given number of pets, and you need to have a record of how many pets are adopted each day and how many pets enter and leave the shelter. In this case, you can use Counter:

Python

>>> from collections import Counter

>>> inventory = Counter(dogs=23, cats=14, pythons=7)

>>> adopted = Counter(dogs=2, cats=5, pythons=1)

>>> inventory.subtract(adopted)

>>> inventory

Counter({'dogs': 21, 'cats': 9, 'pythons': 6})

>>> new_pets = {"dogs": 4, "cats": 1}

>>> inventory.update(new_pets)

>>> inventory

Counter({'dogs': 25, 'cats': 10, 'pythons': 6})

>>> inventory = inventory - Counter(dogs=2, cats=3, pythons=1)

>>> inventory

Counter({'dogs': 23, 'cats': 7, 'pythons': 5})

>>> new_pets = {"dogs": 4, "pythons": 2}

>>> inventory += new_pets

>>> inventory

Counter({'dogs': 27, 'cats': 7, 'pythons': 7})

That’s neat! Now you can keep a record of your pets using Counter. Note that you can use .subtract() and .update() to subtract and add counts or multiplicities. You can also use the addition (+) and subtraction (-) operators.

There’s a lot more you can do with Counter objects as multisets in Python, so go ahead and give it a try!

Remove adsChaining Dictionaries Together: ChainMap

Python’s ChainMap groups multiple dictionaries and other mappings together to create a single object that works pretty much like a regular dictionary. In other words, it takes several mappings and makes them logically appear as one.

ChainMap objects are updateable views, which means that changes in any of the chained mappings affect the ChainMap object as a whole. This is because ChainMap doesn’t merge the input mappings together. It keeps a list of mappings and reimplements common dictionary operations on top of that list. For example, a key lookup searches the list of mappings successively until it finds the key.

Note: Check out Python’s ChainMap: Manage Multiple Contexts Effectively for a deeper dive into using ChainMap in your Python code.

When you’re working with ChainMap objects, you can have several dictionaries with either unique or repeated keys.

In either case, ChainMap allows you to treat all your dictionaries as one. If you have unique keys across your dictionaries, you can access and update the keys as if you were working with a single dictionary.

If you have repeated keys across your dictionaries, besides managing your dictionaries as one, you can also take advantage of the internal list of mappings to define some sort of access priority. Because of this feature, ChainMap objects are great for handling multiple contexts.

For example, say you’re working on a command-line interface (CLI) application. The application allows the user to use a proxy service for connecting to the Internet. The settings priorities are:

Command-line options (--proxy, -p)

Local configuration files in the user’s home directory

Global proxy configuration

If the user supplies a proxy at the command line, then the application must use that proxy. Otherwise, the application should use the proxy provided in the next configuration object, and so on. This is one of the most common use cases of ChainMap. In this situation, you can do the following:

Python

>>> from collections import ChainMap

>>> cmd_proxy = {} # The user doesn't provide a proxy

>>> local_proxy = {"proxy": "proxy.local.com"}

>>> global_proxy = {"proxy": "proxy.global.com"}

>>> config = ChainMap(cmd_proxy, local_proxy, global_proxy)

>>> config["proxy"]

'proxy.local.com'

ChainMap allows you to define the appropriate priority for the application’s proxy configuration. A key lookup searches cmd_proxy, then local_proxy, and finally global_proxy, returning the first instance of the key at hand. In this example, the user doesn’t provide a proxy at the command line, so your application uses the proxy in local_proxy.

In general, ChainMap objects behave similarly to regular dict objects. However, they have some additional features. For example, they have a .maps public attribute that holds the internal list of mappings:

Python

>>> from collections import ChainMap

>>> numbers = {"one": 1, "two": 2}

>>> letters = {"a": "A", "b": "B"}

>>> alpha_nums = ChainMap(numbers, letters)

>>> alpha_nums.maps

[{'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'}]

The instance attribute .maps gives you access to the internal list of mappings. This list is updatable. You can add and remove mappings manually, iterate through the list, and more.

Additionally, ChainMap provides a .new_child() method and a .parents property:

Python

>>> from collections import ChainMap

>>> dad = {"name": "John", "age": 35}

>>> mom = {"name": "Jane", "age": 31}

>>> family = ChainMap(mom, dad)

>>> family

ChainMap({'name': 'Jane', 'age': 31}, {'name': 'John', 'age': 35})

>>> son = {"name": "Mike", "age": 0}

>>> family = family.new_child(son)

>>> for person in family.maps:

... print(person)

...

{'name': 'Mike', 'age': 0}

{'name': 'Jane', 'age': 31}

{'name': 'John', 'age': 35}

>>> family.parents

ChainMap({'name': 'Jane', 'age': 31}, {'name': 'John', 'age': 35})

With .new_child(), you create a new ChainMap object containing a new map (son) followed by all the maps in the current instance. The map passed as a first argument becomes the first map in the list of maps. If you don’t pass a map, then the method uses an empty dictionary.

The parents property returns a new ChainMap objects containing all the maps in the current instance except for the first one. This is useful when you need to skip the first map in a key lookup.

A final feature to highlight in ChainMap is that mutating operations, such as updating keys, adding new keys, deleting existing keys, popping keys, and clearing the dictionary, act on the first mapping in the internal list of mappings:

Python

>>> from collections import ChainMap

>>> numbers = {"one": 1, "two": 2}

>>> letters = {"a": "A", "b": "B"}

>>> alpha_nums = ChainMap(numbers, letters)

>>> alpha_nums

ChainMap({'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'})

>>> # Add a new key-value pair

>>> alpha_nums["c"] = "C"

>>> alpha_nums

ChainMap({'one': 1, 'two': 2, 'c': 'C'}, {'a': 'A', 'b': 'B'})

>>> # Pop a key that exists in the first dictionary

>>> alpha_nums.pop("two")

2

>>> alpha_nums

ChainMap({'one': 1, 'c': 'C'}, {'a': 'A', 'b': 'B'})

>>> # Delete keys that don't exist in the first dict but do in others

>>> del alpha_nums["a"]

Traceback (most recent call last):

...

KeyError: "Key not found in the first mapping: 'a'"

>>> # Clear the dictionary

>>> alpha_nums.clear()

>>> alpha_nums

ChainMap({}, {'a': 'A', 'b': 'B'})

These examples show that mutating operations on a ChainMap object only affect the first mapping in the internal list. This is an important detail to consider when you’re working with ChainMap.

The tricky part is that, at first glance, it could look like it’s possible to mutate any existing key-value pair in a given ChainMap. However, you can only mutate the key-value pairs in the first mapping unless you use .maps to access and mutate other mappings in the list directly.

Remove adsCustomizing Built-Ins: UserString, UserList, and UserDict

Sometimes you need to customize built-in types, such as strings, lists, and dictionaries to add and modify certain behavior. Since Python 2.2, you can do that by subclassing those types directly. However, you could face some issues with this approach, as you’ll see in a minute.

Python’s collections provides three convenient wrapper classes that mimic the behavior of the built-in data types:

UserString

UserList

UserDict

With a combination of regular and special methods, you can use these classes to mimic and customize the behavior of strings, lists, and dictionaries.

Nowadays, developers often ask themselves if there’s a reason to use UserString, UserList, and UserDict when they need to customize the behavior of built-in types. The answer is yes.

Built-in types were designed and implemented with the open-closed principle in mind. This means that they’re open for extension but closed for modification. Allowing modifications on the core features of these classes can potentially break their invariants. So, Python core developers decided to protect them from modifications.

For example, say you need a dictionary that automatically lowercases the keys when you insert them. You could subclass dict and override .__setitem__() so every time you insert a key, the dictionary lowercases the key name:

Python

>>> class LowerDict(dict):

... def __setitem__(self, key, value):

... key = key.lower()

... super().__setitem__(key, value)

...

>>> ordinals = LowerDict({"FIRST": 1, "SECOND": 2})

>>> ordinals["THIRD"] = 3

>>> ordinals.update({"FOURTH": 4})

>>> ordinals

{'FIRST': 1, 'SECOND': 2, 'third': 3, 'FOURTH': 4}

>>> isinstance(ordinals, dict)

True

This dictionary works correctly when you insert new keys using dictionary-style assignment with square brackets ([]). However, it doesn’t work when you pass an initial dictionary to the class constructor or when you use .update(). This means that you would need to override .__init__(), .update(), and probably some other methods for your custom dictionary to work correctly.

Now take a look at the same dictionary but using UserDict as a base class:

Python

>>> from collections import UserDict

>>> class LowerDict(UserDict):

... def __setitem__(self, key, value):

... key = key.lower()

... super().__setitem__(key, value)

...

>>> ordinals = LowerDict({"FIRST": 1, "SECOND": 2})

>>> ordinals["THIRD"] = 3

>>> ordinals.update({"FOURTH": 4})

>>> ordinals

{'first': 1, 'second': 2, 'third': 3, 'fourth': 4}

>>> isinstance(ordinals, dict)

False

It works! Your custom dictionary now converts all the new keys into lowercase letters before inserting them into the dictionary. Note that since you don’t inherit from dict directly, your class doesn’t return instances of dict as in the example above.

UserDict stores a regular dictionary in an instance attribute called .data. Then it implements all its methods around that dictionary. UserList and UserString work the same way, but their .data attribute holds a list and a str object, respectively.

If you need to customize either of these classes, then you just need to override the appropriate methods and change what they do as required.

In general, you should use UserDict, UserList, and UserString when you need a class that acts almost identically to the underlying wrapped built-in class and you want to customize some part of its standard functionalities.

Another reason to use these classes rather than the built-in equivalent classes is to access the underlying .data attribute to manipulate it directly.

The ability to inherit from built-in types directly has largely superseded the use of UserDict, UserList, and UserString. However, the internal implementation of built-in types makes it hard to safely inherit from them without rewriting a significant amount of code. In most cases, it’s safer to use the appropriate class from collections. It’ll save you from several issues and weird behaviors.

Conclusion

In Python’s collections module, you have several specialized container data types that you can use to approach common programming problems, such as counting objects, creating queues and stacks, handling missing keys in dictionaries, and more.

The data types and classes in collections were designed to be efficient and Pythonic. They can be tremendously helpful in your Python programming journey, so learning about them is well worth your time and effort.

In this tutorial, you learned how to:

Write readable and explicit code using namedtuple

Build efficient queues and stacks using deque

Count objects efficiently using Counter

Handle missing dictionary keys with defaultdict

Remember the insertion order of keys with OrderedDict

Chain multiple dictionaries in a single view with ChainMap

You also learned about three convenient wrapper classes: UserDict, UserList, and UserString. These classes are handy when you need to create custom classes that mimic the behavior of the built-in types dict, list, and str.

Mark as Completed

Python Tricks

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Send Me Python Tricks »

About Leodanis Pozo Ramos

Leodanis is an industrial engineer who loves Python and software development. He's a self-taught Python developer with 6+ years of experience. He's an avid technical writer with a growing number of articles published on Real Python and other sites.

» More about Leodanis

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Aldren

Bartosz

Geir Arne

Joanna

Jacob

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python SkillsWith Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

LinkedIn

Twitter

Facebook

Email

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal.Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!

Keep Learning

Related Tutorial Categories:

data-structures

intermediate

python

Keep reading Real Python by creating a free account or signing in:

Continue »

Already have an account? Sign-In

Almost there! Complete this form and click the button below to gain instant access:

×

"Python Tricks: The Book" – Free Sample Chapter (PDF)

Send My Sample Chapter »

No spam. We take your privacy seriously.

Remove ads

© 2012–2024 Real Python ⋅ Newsletter ⋅ Podcast ⋅ YouTube ⋅ Twitter ⋅ Facebook ⋅ Instagram ⋅ Python Tutorials ⋅ Search ⋅ Privacy Policy ⋅ Energy Policy ⋅ Advertise ⋅ Contact Happy Pythoning!

集合 — 容器数据类型 — Python 文档 - 菜鸟教程

集合 — 容器数据类型 — Python 文档 - 菜鸟教程

首页

随机页面

分类

集合 — 容器数据类型 — Python 文档

来自菜鸟教程

Python/docs/3.7/library/collections跳转至:导航、​搜索

目录

1 collections — 容器数据类型

1.1 ChainMap 对象

1.1.1 ChainMap 例子和食谱

1.2 计数器对象

1.3 deque 对象

1.3.1 deque 食谱

1.4 defaultdict 对象

1.4.1 defaultdict 示例

1.5 namedtuple() 具有命名字段的元组的工厂函数

1.6 OrderedDict 对象

1.6.1 OrderedDict 例子和食谱

1.7 UserDict 对象

1.8 UserList 对象

1.9 UserString 对象

collections — 容器数据类型

源代码: :source:`Lib/collections/__init__.py`

该模块实现了专门的容器数据类型,为 Python 的通用内置容器 dict、list、set 和 tuple 提供了替代方案。

namedtuple()

用于创建具有命名字段的元组子类的工厂函数

deque

类似列表的容器,两端具有快速追加和弹出

ChainMap

用于创建多个映射的单个视图的类 dict 类

Counter

用于计算可散列对象的 dict 子类

OrderedDict

添加了记住订单条目的 dict 子类

defaultdict

dict 子类调用工厂函数来提供缺失值

UserDict

围绕字典对象的包装器,以便于 dict 子类化

UserList

列表对象的包装器,以便于列表子类化

UserString

围绕字符串对象的包装器,以便于字符串子类化

ChainMap 对象

3.3 版中的新功能。

提供了一个 ChainMap 类,用于快速链接多个映射,以便将它们视为一个单元。 它通常比创建新字典并运行多个 update() 调用快得多。

该类可用于模拟嵌套作用域,并可用于模板化。

class collections.ChainMap(*maps)

ChainMap 将多个字典或其他映射组合在一起以创建单个可更新视图。 如果未指定 maps,则提供单个空字典,以便新链始终具有至少一个映射。

底层映射存储在一个列表中。 该列表是公开的,可以使用 maps 属性访问或更新。 没有其他状态。

查找会连续搜索底层映射,直到找到一个键。 相比之下,写入、更新和删除仅对第一个映射进行操作。

ChainMap 通过引用合并了底层映射。 因此,如果底层映射之一得到更新,这些更改将反映在 ChainMap 中。

支持所有常用的字典方法。 此外,还有一个 maps 属性,一个用于创建新子上下文的方法,以及一个用于访问除第一个映射之外的所有映射的属性:

maps

用户可更新的映射列表。 该列表按从第一个搜索到最后一个搜索的顺序排列。 它是唯一的存储状态,可以修改以更改要搜索的映射。 该列表应始终包含至少一个映射。

new_child(m=None)

返回一个新的 ChainMap,其中包含一个新地图,后跟当前实例中的所有地图。 如果指定了 m,则它成为映射列表最前面的新映射; 如果未指定,则使用空字典,因此对 d.new_child() 的调用等效于:ChainMap({}, *d.maps)。 此方法用于创建可以在不更改任何父映射中的值的情况下更新的子上下文。

3.4 版更改: 增加了可选的 m 参数。

parents

属性返回一个新的 ChainMap,其中包含当前实例中除第一个之外的所有地图。 这对于跳过搜索中的第一个地图很有用。 用例类似于 嵌套作用域 中使用的 nonlocal 关键字的用例。 这些用例还与内置 super() 函数的用例并行。 对 d.parents 的引用相当于:ChainMap(*d.maps[1:])。

注意,ChainMap() 的迭代顺序是通过扫描从后到前的映射来确定的:

>>> baseline = {'music': 'bach', 'art': 'rembrandt'}

>>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}

>>> list(ChainMap(adjustments, baseline))

['music', 'art', 'opera']

这给出了与从最后一个映射开始的一系列 dict.update() 调用相同的顺序:

>>> combined = baseline.copy()

>>> combined.update(adjustments)

>>> list(combined)

['music', 'art', 'opera']

也可以看看

Enthought CodeTools 包 中的 MultiContext 类 具有支持写入链中任何映射的选项。

Django 的 上下文类 用于模板化是一个只读的映射链。 它还具有类似于 new_child() 方法和 parents 属性的上下文推送和弹出功能。

嵌套上下文配方 具有控制写入和其他更改是仅应用于第一个映射还是链中的任何映射的选项。

一个 大大简化的 Chainmap 只读版本。

ChainMap 例子和食谱

本节展示了使用链式地图的各种方法。

模拟Python内部查找链的例子:

import builtins

pylookup = ChainMap(locals(), globals(), vars(builtins))

让用户指定的命令行参数优先于环境变量的示例,而环境变量又优先于默认值:

import os, argparse

defaults = {'color': 'red', 'user': 'guest'}

parser = argparse.ArgumentParser()

parser.add_argument('-u', '--user')

parser.add_argument('-c', '--color')

namespace = parser.parse_args()

command_line_args = {k: v for k, v in vars(namespace).items() if v is not None}

combined = ChainMap(command_line_args, os.environ, defaults)

print(combined['color'])

print(combined['user'])

使用 ChainMap 类模拟嵌套上下文的示例模式:

c = ChainMap() # Create root context

d = c.new_child() # Create nested child context

e = c.new_child() # Child of c, independent from d

e.maps[0] # Current context dictionary -- like Python's locals()

e.maps[-1] # Root context -- like Python's globals()

e.parents # Enclosing context chain -- like Python's nonlocals

d['x'] = 1 # Set value in current context

d['x'] # Get first key in the chain of contexts

del d['x'] # Delete from current context

list(d) # All nested values

k in d # Check all nested values

len(d) # Number of nested values

d.items() # All nested items

dict(d) # Flatten into a regular dictionary

ChainMap 类只对链中的第一个映射进行更新(写入和删除),而查找将搜索整个链。 但是,如果需要深度写入和删除,很容易创建一个子类来更新链中更深层次的键:

class DeepChainMap(ChainMap):

'Variant of ChainMap that allows direct updates to inner scopes'

def __setitem__(self, key, value):

for mapping in self.maps:

if key in mapping:

mapping[key] = value

return

self.maps[0][key] = value

def __delitem__(self, key):

for mapping in self.maps:

if key in mapping:

del mapping[key]

return

raise KeyError(key)

>>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})

>>> d['lion'] = 'orange' # update an existing key two levels down

>>> d['snake'] = 'red' # new keys get added to the topmost dict

>>> del d['elephant'] # remove an existing key one level down

>>> d # display result

DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})

计数器对象

提供了一个计数器工具来支持方便和快速的计数。 例如:

>>> # Tally occurrences of words in a list

>>> cnt = Counter()

>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:

... cnt[word] += 1

>>> cnt

Counter({'blue': 3, 'red': 2, 'green': 1})

>>> # Find the ten most common words in Hamlet

>>> import re

>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())

>>> Counter(words).most_common(10)

[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),

('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]

class collections.Counter([iterable-or-mapping])

Counter 是一个 dict 子类,用于计算可散列对象。 它是一个集合,其中元素存储为字典键,它们的计数存储为字典值。 计数可以是任何整数值,包括零或负计数。 Counter 类类似于其他语言中的 bag 或 multisets。

元素从 可迭代 计数或从另一个 映射 (或计数器)初始化:

>>> c = Counter() # a new, empty counter

>>> c = Counter('gallahad') # a new counter from an iterable

>>> c = Counter({'red': 4, 'blue': 2}) # a new counter from a mapping

>>> c = Counter(cats=4, dogs=8) # a new counter from keyword args

Counter 对象有一个字典接口,除了它们为丢失的项目返回零计数而不是引发 KeyError:

>>> c = Counter(['eggs', 'ham'])

>>> c['bacon'] # count of a missing element is zero

0

将计数设置为零不会从计数器中删除元素。 使用 del 将其完全删除:

>>> c['sausage'] = 0 # counter entry with a zero count

>>> del c['sausage'] # del actually removes the entry

3.1 版中的新功能。

Counter 对象支持三种超出所有字典可用的方法:

elements()

在元素上返回一个迭代器,每个元素的重复次数与其计数相同。 元素以任意顺序返回。 如果元素的计数小于 1,则 elements() 将忽略它。

>>> c = Counter(a=4, b=2, c=0, d=-2)

>>> sorted(c.elements())

['a', 'a', 'a', 'a', 'b', 'b']

most_common([n])

返回 n 最常见元素的列表及其从最常见到最少的计数。 如果省略 n 或 None,则 most_common() 返回计数器中的 all 元素。 具有相等计数的元素被任意排序:

>>> Counter('abracadabra').most_common(3)

[('a', 5), ('r', 2), ('b', 2)]

subtract([iterable-or-mapping])

从 可迭代 或另一个 映射 (或计数器)中减去元素。 像 dict.update() 但减去计数而不是替换它们。 输入和输出都可以为零或负。

>>> c = Counter(a=4, b=2, c=0, d=-2)

>>> d = Counter(a=1, b=2, c=3, d=4)

>>> c.subtract(d)

>>> c

Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

3.2 版中的新功能。

通常的字典方法可用于 Counter 对象,除了两个对计数器的工作方式不同。

fromkeys(iterable)

此类方法未为 Counter 对象实现。

update([iterable-or-mapping])

元素从 可迭代 计数或从另一个 映射 (或计数器)添加。 像 dict.update() 但增加计数而不是替换它们。 此外,iterable 应该是一个元素序列,而不是一个 (key, value) 对序列。

使用 Counter 对象的常见模式:

sum(c.values()) # total of all counts

c.clear() # reset all counts

list(c) # list unique elements

set(c) # convert to a set

dict(c) # convert to a regular dictionary

c.items() # convert to a list of (elem, cnt) pairs

Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs

c.most_common()[:-n-1:-1] # n least common elements

+c # remove zero and negative counts

提供了几种数学运算来组合 Counter 对象以生成多重集(计数大于零的计数器)。 加法和减法通过增加或减去相应元素的计数来组合计数器。 交集和并集返回对应计数的最小值和最大值。 每个操作都可以接受带符号计数的输入,但输出将排除计数为零或更少的结果。

>>> c = Counter(a=3, b=1)

>>> d = Counter(a=1, b=2)

>>> c + d # add two counters together: c[x] + d[x]

Counter({'a': 4, 'b': 3})

>>> c - d # subtract (keeping only positive counts)

Counter({'a': 2})

>>> c & d # intersection: min(c[x], d[x])

Counter({'a': 1, 'b': 1})

>>> c | d # union: max(c[x], d[x])

Counter({'a': 3, 'b': 2})

一元加法和减法是添加空计数器或从空计数器中减去的快捷方式。

>>> c = Counter(a=2, b=-4)

>>> +c

Counter({'a': 2})

>>> -c

Counter({'b': 4})

3.3 新功能: 增加了对一元加、一元减和就地多集操作的支持。

笔记

计数器主要设计为使用正整数来表示运行计数; 但是,注意不要不必要地排除需要其他类型或负值的用例。 为了帮助处理这些用例,本节记录了最小范围和类型限制。

Counter 类本身是一个字典子类,对其键和值没有限制。 这些值旨在是表示计数的数字,但您 可以 在值字段中存储任何内容。

most_common() 方法只要求值是可排序的。

对于c[key] += 1等就地操作,值类型只需要支持加减。 因此分数、浮点数和小数都可以使用,并且支持负值。 update() 和 subtract() 也是如此,它们允许输入和输出的负值和零值。

多集方法仅适用于具有正值的用例。 输入可能是负数或零,但只会创建具有正值的输出。 没有类型限制,但是值类型需要支持加减比较。

elements() 方法需要整数计数。 它忽略零和负计数。

也可以看看

Smalltalk 中的包类 。

Multisets 的维基百科条目。

C++ multisets 教程示例。

有关多重集及其用例的数学运算,请参阅克努斯,唐纳德。 计算机编程艺术第二卷,第 4.6.3 节,练习 19 .

要枚举给定元素集上给定大小的所有不同多重集,请参阅 itertools.combinations_with_replacement():

map(Counter, combinations_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC

deque 对象

class collections.deque([iterable[, maxlen]])

返回一个从左到右初始化的新 deque 对象(使用 append()),数据来自 iterable。 如果未指定 iterable,则新的双端队列为空。

双端队列是栈和队列的泛化(名称发音为“deck”,是“双端队列”的缩写)。 双端队列支持线程安全、内存高效的追加和从双端队列的任一侧弹出,在任一方向上的 O(1) 性能大致相同。

尽管 list 对象支持类似的操作,但它们针对快速固定长度的操作进行了优化,并为 pop(0) 和 insert(0, v) 操作产生 O(n) 内存移动成本,这改变了底层数据表示的大小和位置。

如果未指定 maxlen 或 None,则双端队列可能会增长到任意长度。 否则,双端队列受限于指定的最大长度。 一旦有界长度的双端队列已满,当添加新项目时,从另一端丢弃相应数量的项目。 有界长度的双端队列提供类似于 Unix 中的 tail 过滤器的功能。 它们还可用于跟踪仅对最近的活动感兴趣的交易和其他数据池。

Deque 对象支持以下方法:

append(x)

将 x 添加到双端队列的右侧。

appendleft(x)

将 x 添加到双端队列的左侧。

clear()

从双端队列中删除所有元素,使其长度为 0。

copy()

创建双端队列的浅拷贝。

3.5 版中的新功能。

count(x)

计算等于 x 的双端队列元素的数量。

3.2 版中的新功能。

extend(iterable)

通过附加来自可迭代参数的元素来扩展双端队列的右侧。

extendleft(iterable)

通过附加来自 iterable 的元素来扩展双端队列的左侧。 请注意,一系列左追加会导致可迭代参数中元素的顺序颠倒。

index(x[, start[, stop]])

返回 x 在双端队列中的位置(在索引 start 处或之后和索引 stop 之前)。 如果未找到,则返回第一个匹配项或引发 ValueError。

3.5 版中的新功能。

insert(i, x)

将 x 插入双端队列中的位置 i。

如果插入会导致有界双端队列增长超过 maxlen,则会引发 IndexError。

3.5 版中的新功能。

pop()

从双端队列的右侧移除并返回一个元素。 如果不存在元素,则引发 IndexError。

popleft()

从双端队列的左侧移除并返回一个元素。 如果不存在元素,则引发 IndexError。

remove(value)

删除第一次出现的 值 。 如果未找到,则引发 ValueError。

reverse()

原地反转双端队列的元素,然后返回 None。

3.2 版中的新功能。

rotate(n=1)

向右旋转双端队列 n 步。 如果 n 为负,则向左旋转。

当双端队列不为空时,向右旋转一级相当于d.appendleft(d.pop()),向左旋转一级相当于d.append(d.popleft())。

Deque 对象还提供了一个只读属性:

maxlen

双端队列的最大大小或 None 如果无界。

3.1 版中的新功能。

除上述之外,双端队列支持迭代、酸洗、len(d)、reversed(d)、copy.copy(d)、copy.deepcopy(d)、in的成员资格测试] 运算符,以及下标引用,例如 d[-1]。 索引访问在两端都是 O(1),但在中间变慢到 O(n)。 对于快速随机访问,请改用列表。

从 3.5 版开始,双端队列支持 __add__()、__mul__() 和 __imul__()。

例子:

>>> from collections import deque

>>> d = deque('ghi') # make a new deque with three items

>>> for elem in d: # iterate over the deque's elements

... print(elem.upper())

G

H

I

>>> d.append('j') # add a new entry to the right side

>>> d.appendleft('f') # add a new entry to the left side

>>> d # show the representation of the deque

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

>>> d.pop() # return and remove the rightmost item

'j'

>>> d.popleft() # return and remove the leftmost item

'f'

>>> list(d) # list the contents of the deque

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

>>> d[0] # peek at leftmost item

'g'

>>> d[-1] # peek at rightmost item

'i'

>>> list(reversed(d)) # list the contents of a deque in reverse

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

>>> 'h' in d # search the deque

True

>>> d.extend('jkl') # add multiple elements at once

>>> d

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

>>> d.rotate(1) # right rotation

>>> d

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

>>> d.rotate(-1) # left rotation

>>> d

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

>>> deque(reversed(d)) # make a new deque in reverse order

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

>>> d.clear() # empty the deque

>>> d.pop() # cannot pop from an empty deque

Traceback (most recent call last):

File "", line 1, in -toplevel-

d.pop()

IndexError: pop from an empty deque

>>> d.extendleft('abc') # extendleft() reverses the input order

>>> d

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

deque 食谱

本节展示了使用双端队列的各种方法。

有界长度的双端队列提供类似于 Unix 中的 tail 过滤器的功能:

def tail(filename, n=10):

'Return the last n lines of a file'

with open(filename) as f:

return deque(f, n)

使用双端队列的另一种方法是通过添加到右侧并从左侧弹出来维护最近添加的元素序列:

def moving_average(iterable, n=3):

# moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0

# http://en.wikipedia.org/wiki/Moving_average

it = iter(iterable)

d = deque(itertools.islice(it, n-1))

d.appendleft(0)

s = sum(d)

for elem in it:

s += elem - d.popleft()

d.append(elem)

yield s / n

循环调度器可以用存储在deque中的输入迭代器来实现。 值是从位置零的活动迭代器产生的。 如果该迭代器耗尽,则可以使用 popleft() 将其删除; 否则,可以使用 rotate() 方法循环回到最后:

def roundrobin(*iterables):

"roundrobin('ABC', 'D', 'EF') --> A D E B F C"

iterators = deque(map(iter, iterables))

while iterators:

try:

while True:

yield next(iterators[0])

iterators.rotate(-1)

except StopIteration:

# Remove an exhausted iterator.

iterators.popleft()

rotate() 方法提供了一种实现 deque 切片和删除的方法。 例如,del d[n] 的纯 Python 实现依赖于 rotate() 方法来定位要弹出的元素:

def delete_nth(d, n):

d.rotate(-n)

d.popleft()

d.rotate(n)

要实现 deque 切片,请使用类似的方法应用 rotate() 将目标元素带到双端队列的左侧。 使用 popleft() 删除旧条目,使用 extend() 添加新条目,然后反向旋转。 通过对该方法的微小改动,很容易实现 Forth 风格的堆栈操作,例如 dup、drop、swap、over、[ X152X]、rot 和 roll。

defaultdict 对象

class collections.defaultdict([default_factory[, ...]])

返回一个新的类似字典的对象。 defaultdict 是内置的 dict 类的子类。 它覆盖了一种方法并添加了一个可写的实例变量。 其余功能与 dict 类相同,此处未记录。

第一个参数提供 default_factory 属性的初始值; 默认为 None。 所有剩余的参数都被视为传递给 dict 构造函数,包括关键字参数。

defaultdict 对象除了标准的 dict 操作之外还支持以下方法:

__missing__(key)

如果 default_factory 属性为 None,则会引发 KeyError 异常,并以 key 作为参数。

如果 default_factory 不是 None,则不带参数调用它以提供给定 key 的默认值,该值被插入到 的字典中键,并返回。

如果调用 default_factory 引发异常,则此异常将保持不变地传播。

该方法在没有找到请求的key时由dict类的__getitem__()方法调用; 无论它返回或引发什么,然后由 __getitem__() 返回或引发。

请注意,__missing__() 不是 不是 调用除 __getitem__() 之外的任何操作。 这意味着 get() 将像普通字典一样返回 None 作为默认值,而不是使用 default_factory。

defaultdict 对象支持以下实例变量:

default_factory

该属性由 __missing__() 方法使用; 它从构造函数的第一个参数(如果存在)或 None(如果不存在)初始化。

defaultdict 示例

使用 list 作为 default_factory,可以很容易地将键值对序列分组到列表字典中:

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

>>> d = defaultdict(list)

>>> for k, v in s:

... d[k].append(v)

...

>>> sorted(d.items())

[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

第一次遇到每个键时,它尚未在映射中; 因此使用 default_factory 函数自动创建一个条目,该函数返回一个空的 列表 。 list.append() 操作然后将该值附加到新列表。 当再次遇到键时,查找将正常进行(返回该键的列表)并且 list.append() 操作将另一个值添加到列表中。 这种技术比使用 dict.setdefault() 的等效技术更简单、更快:

>>> d = {}

>>> for k, v in s:

... d.setdefault(k, []).append(v)

...

>>> sorted(d.items())

[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

将 default_factory 设置为 int 使 defaultdict 可用于计数(如其他语言中的包或多重集):

>>> s = 'mississippi'

>>> d = defaultdict(int)

>>> for k in s:

... d[k] += 1

...

>>> sorted(d.items())

[('i', 4), ('m', 1), ('p', 2), ('s', 4)]

当第一次遇到字母时,它从映射中丢失,因此 default_factory 函数调用 int() 以提供默认计数为零。 增量操作然后建立每个字母的计数。

总是返回零的函数 int() 只是常量函数的一个特例。 创建常量函数的一种更快、更灵活的方法是使用可以提供任何常量值(不仅仅是零)的 lambda 函数:

>>> def constant_factory(value):

... return lambda: value

>>> d = defaultdict(constant_factory(''))

>>> d.update(name='John', action='ran')

>>> '%(name)s %(action)s to %(object)s' % d

'John ran to '

将 default_factory 设置为 set 使 defaultdict 可用于构建集合字典:

>>> 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)

...

>>> sorted(d.items())

[('blue', {2, 4}), ('red', {1, 3})]

namedtuple() 具有命名字段的元组的工厂函数

命名元组为元组中的每个位置分配含义,并允许更具可读性、自文档化的代码。 它们可以在使用常规元组的任何地方使用,并且它们增加了按名称而不是位置索引访问字段的能力。

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

返回一个名为 typename 的新元组子类。 新的子类用于创建类似元组的对象,这些对象具有可通过属性查找访问的字段以及可索引和可迭代的。 子类的实例也有一个有用的文档字符串(带有 typename 和 field_names)和一个有用的 __repr__() 方法,它以 name=value 格式列出元组内容。

field_names 是一个字符串序列,例如 ['x', 'y']。 或者,field_names 可以是单个字符串,每个字段名由空格和/或逗号分隔,例如 'x y' 或 'x, y'。

除了以下划线开头的名称外,任何有效的 Python 标识符都可用于字段名。 有效标识符由字母、数字和下划线组成,但不以数字或下划线开头,并且不能是 关键字 ,例如 class、for、 ]return、global、pass或raise。

如果 rename 为真,无效的字段名会自动替换为位置名称。 例如,将 ['abc', 'def', 'ghi', 'abc'] 转换为 ['abc', '_1', 'ghi', '_3'],消除关键字 def 和重复的字段名 abc。

defaults 可以是 None 或默认值的 iterable。 由于具有默认值的字段必须位于没有默认值的任何字段之后,因此 defaults 应用于最右边的参数。 例如,如果字段名称为 ['x', 'y', 'z'] 且默认值为 (1, 2),则 x 将是必需参数,y 将默认为 [ X151X] 和 z 将默认为 2。

如果定义了 module,则命名元组的 __module__ 属性设置为该值。

命名元组实例没有每个实例的字典,因此它们是轻量级的,不需要比常规元组更多的内存。

3.1 版更改: 添加了对 重命名 的支持。

3.6 版更改: verbose 和 rename 参数变为 仅关键字参数 。

3.6 版更改: 增加了 模块 参数。

3.7 版更改: 删除 verbose 参数和 _source 属性。

3.7 版更改: 添加 defaults 参数和 _field_defaults 属性。

>>> # Basic example

>>> Point = namedtuple('Point', ['x', 'y'])

>>> p = Point(11, y=22) # instantiate with positional or keyword arguments

>>> p[0] + p[1] # indexable like the plain tuple (11, 22)

33

>>> x, y = p # unpack like a regular tuple

>>> x, y

(11, 22)

>>> p.x + p.y # fields also accessible by name

33

>>> p # readable __repr__ with a name=value style

Point(x=11, y=22)

命名元组对于将字段名称分配给 csv 或 sqlite3 模块返回的结果元组特别有用:

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv

for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):

print(emp.name, emp.title)

import sqlite3

conn = sqlite3.connect('/companydata')

cursor = conn.cursor()

cursor.execute('SELECT name, age, title, department, paygrade FROM employees')

for emp in map(EmployeeRecord._make, cursor.fetchall()):

print(emp.name, emp.title)

除了从元组继承的方法之外,命名元组还支持三个附加方法和两个属性。 为防止与字段名称冲突,方法和属性名称以下划线开头。

classmethod somenamedtuple._make(iterable)

从现有序列或可迭代创建新实例的类方法。

>>> t = [11, 22]

>>> Point._make(t)

Point(x=11, y=22)

somenamedtuple._asdict()

返回一个新的 dict,它将字段名称映射到它们对应的值:

>>> p = Point(x=11, y=22)

>>> p._asdict()

OrderedDict([('x', 11), ('y', 22)])

在 3.1 版中更改: 返回 OrderedDict 而不是常规的 dict。

somenamedtuple._replace(**kwargs)

返回命名元组的新实例,用新值替换指定字段:

>>> p = Point(x=11, y=22)

>>> p._replace(x=33)

Point(x=33, y=22)

>>> for partnum, record in inventory.items():

... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())

somenamedtuple._fields

列出字段名称的字符串元组。 用于内省和从现有命名元组创建新的命名元组类型。

>>> p._fields # view the field names

('x', 'y')

>>> Color = namedtuple('Color', 'red green blue')

>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)

>>> Pixel(11, 22, 128, 255, 0)

Pixel(x=11, y=22, red=128, green=255, blue=0)

somenamedtuple._field_defaults

将字段名称映射到默认值的字典。

>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])

>>> Account._field_defaults

{'balance': 0}

>>> Account('premium')

Account(type='premium', balance=0)

要检索名称存储在字符串中的字段,请使用 getattr() 函数:

>>> getattr(p, 'x')

11

要将字典转换为命名元组,请使用 ** 运算符(如 解包参数列表 中所述):

>>> d = {'x': 11, 'y': 22}

>>> Point(**d)

Point(x=11, y=22)

由于命名元组是一个常规的 Python 类,因此很容易使用子类添加或更改功能。 以下是添加计算字段和固定宽度打印格式的方法:

>>> class Point(namedtuple('Point', ['x', 'y'])):

... __slots__ = ()

... @property

... def hypot(self):

... return (self.x ** 2 + self.y ** 2) ** 0.5

... def __str__(self):

... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)

>>> for p in Point(3, 4), Point(14, 5/7):

... print(p)

Point: x= 3.000 y= 4.000 hypot= 5.000

Point: x=14.000 y= 0.714 hypot=14.018

上面显示的子类将 __slots__ 设置为一个空元组。 这有助于通过防止创建实例字典来保持较低的内存要求。

子类化对于添加新的存储字段没有用处。 相反,只需从 _fields 属性创建一个新的命名元组类型:

>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))

可以通过直接分配给 __doc__ 字段来自定义文档字符串:

>>> Book = namedtuple('Book', ['id', 'title', 'authors'])

>>> Book.__doc__ += ': Hardcover book in active collection'

>>> Book.id.__doc__ = '13-digit ISBN'

>>> Book.title.__doc__ = 'Title of first printing'

>>> Book.authors.__doc__ = 'List of authors sorted by last name'

3.5 版更改: 属性文档字符串变为可写。

可以通过使用 _replace() 自定义原型实例来实现默认值:

>>> Account = namedtuple('Account', 'owner balance transaction_count')

>>> default_account = Account('', 0.0, 0)

>>> johns_account = default_account._replace(owner='John')

>>> janes_account = default_account._replace(owner='Jane')

也可以看看

有关为命名元组添加类型提示的方法,请参阅 typing.NamedTuple。 它还使用 class 关键字提供了一种优雅的表示法:

class Component(NamedTuple):

part_number: int

weight: float

description: Optional[str] = None

有关基于底层字典而不是元组的可变命名空间,请参阅 types.SimpleNamespace()。

dataclasses 模块提供了一个装饰器和函数,用于将生成的特殊方法自动添加到用户定义的类中。

OrderedDict 对象

有序字典就像普通字典一样,但有一些与排序操作相关的额外功能。 由于内置的 dict 类获得了记住插入顺序的能力(这种新行为在 Python 3.7 中得到保证),它们变得不那么重要了。

与 dict 的一些差异仍然存在:

常规的 dict 被设计为非常擅长映射操作。 跟踪广告订单是次要的。

OrderedDict 旨在擅长重新排序操作。 空间效率、迭代速度和更新操作的性能是次要的。

在算法上,OrderedDict 可以比 dict 更好地处理频繁的重新排序操作。 这使它适合跟踪最近的访问(例如在 LRU 缓存 中)。

OrderedDict 的相等运算检查匹配顺序。

OrderedDict 的 popitem() 方法具有不同的签名。 它接受一个可选参数来指定弹出哪个项目。

OrderedDict 有一个 move_to_end() 方法可以有效地将元素重新定位到端点。

在 Python 3.8 之前, dict 缺少 __reversed__() 方法。

class collections.OrderedDict([items])

返回一个 dict 子类的实例,该子类具有专门用于重新排列字典顺序的方法。

3.1 版中的新功能。

popitem(last=True)

有序字典的 popitem() 方法返回并删除一个 (key, value) 对。 如果 last 为真,则按 LIFO 顺序返回,如果为假,则按 FIFO 顺序返回。

move_to_end(key, last=True)

将现有的 键 移动到有序字典的任一端。 如果 last 为真(默认值),则项目移至右端,如果 last 为假,则移至开头。 如果 键 不存在,则引发 KeyError:

>>> d = OrderedDict.fromkeys('abcde')

>>> d.move_to_end('b')

>>> ''.join(d.keys())

'acdeb'

>>> d.move_to_end('b', last=False)

>>> ''.join(d.keys())

'bacde'

3.2 版中的新功能。

除了通常的映射方法,有序字典还支持使用 reversed() 的反向迭代。

OrderedDict 对象之间的相等性测试是顺序敏感的,并且实现为 list(od1.items())==list(od2.items())。 OrderedDict 对象和其他 Mapping 对象之间的相等性测试与常规字典一样对顺序不敏感。 这允许在使用常规字典的任何地方替换 OrderedDict 对象。

3.5 版更改: OrderedDict 的项目、键和值 views 现在支持使用 reversed() 进行反向迭代。

在 3.6 版更改:随着接受 PEP 468,保留传递给 OrderedDict 构造函数及其 [ X178X] 方法。

OrderedDict 例子和食谱

创建一个有序的字典变体很简单,它记住键 last 插入的顺序。 如果新条目覆盖现有条目,则更改原始插入位置并移至末尾:

class LastUpdatedOrderedDict(OrderedDict):

'Store items in the order the keys were last added'

def __setitem__(self, key, value):

super().__setitem__(key, value)

super().move_to_end(key)

OrderedDict 也可用于实现 functools.lru_cache() 的变体:

class LRU(OrderedDict):

'Limit size, evicting the least recently looked-up key when full'

def __init__(self, maxsize=128, *args, **kwds):

self.maxsize = maxsize

super().__init__(*args, **kwds)

def __getitem__(self, key):

value = super().__getitem__(key)

self.move_to_end(key)

return value

def __setitem__(self, key, value):

super().__setitem__(key, value)

if len(self) > self.maxsize:

oldest = next(iter(self))

del self[oldest]

UserDict 对象

类 UserDict 充当字典对象的包装器。 对此类的需求已部分被直接从 dict 子类化的能力所取代; 但是,这个类更容易使用,因为底层字典可以作为属性访问。

class collections.UserDict([initialdata])

模拟字典的类。 实例的内容保存在常规字典中,可通过 UserDict 实例的 data 属性访问。 如果提供了 initialdata,则用其内容初始化 data; 请注意,不会保留对 initialdata 的引用,允许将其用于其他目的。

除了支持映射的方法和操作外,UserDict 实例还提供以下属性:

data

一个真正的字典,用于存储 UserDict 类的内容。

UserList 对象

此类充当列表对象的包装器。 它是您自己的类似列表的类的有用基类,可以从它们继承并覆盖现有方法或添加新方法。 通过这种方式,人们可以向列表添加新的行为。

对此类的需求已部分被直接从 list 子类化的能力所取代; 但是,这个类更容易使用,因为底层列表可以作为属性访问。

class collections.UserList([list])

模拟列表的类。 实例的内容保存在一个常规列表中,可以通过 UserList 实例的 data 属性访问该列表。 实例的内容最初设置为 list 的副本,默认为空列表 []。 list 可以是任何可迭代对象,例如真正的 Python 列表或 UserList 对象。

除了支持可变序列的方法和操作外,UserList 实例还提供以下属性:

data

一个真正的 list 对象,用于存储 UserList 类的内容。

子类化要求: UserList 的子类应提供一个构造函数,该构造函数可以不带参数或一个参数调用。 返回新序列的列表操作尝试创建实际实现类的实例。 为此,它假定可以使用单个参数调用构造函数,该参数是用作数据源的序列对象。

如果派生类不希望遵守此要求,则需要覆盖该类支持的所有特殊方法; 有关在这种情况下需要提供的方法的信息,请咨询来源。

UserString 对象

类 UserString 充当字符串对象的包装器。 对此类的需求已部分被直接从 str 子类化的能力所取代; 但是,这个类更容易使用,因为底层字符串可以作为属性访问。

class collections.UserString(seq)

模拟字符串对象的类。 实例的内容保存在一个常规字符串对象中,该对象可通过 UserString 实例的 data 属性访问。 实例的内容最初设置为 seq 的副本。 seq 参数可以是任何可以使用内置 str() 函数转换为字符串的对象。

UserString 实例除了支持字符串的方法和操作外,还提供以下属性:

data

一个真正的 str 对象,用于存储 UserString 类的内容。

3.5 版本更改:新方法 __getnewargs__、__rmod__、casefold、format_map、isprintable 和 [ X104X]。

取自“https://cainiaojiaocheng.com/index.php?title=Python/docs/3.7/library/collections&oldid=24063”

分类:​Python 3.7 文档

隐私政策

关于菜鸟教程

免责声明

京ICP备19005578号-2

如何在 Python 中使用 collections 模块? - 知乎

如何在 Python 中使用 collections 模块? - 知乎首页知乎知学堂发现等你来答​切换模式登录/注册Python计算机技术Python 入门Python 开发Python教程如何在 Python 中使用 collections 模块?关注者8被浏览2,581关注问题​写回答​邀请回答​好问题​添加评论​分享​5 个回答默认排序pythontip热爱生活,自由编码,创造美好世界​ 关注 Python 中的 collections 模块实现了专门的容器数据类型, 为 Python 的通用内置容器: dict、list、set 和 tuple 提供了替代方案。主要包括以下工具:namedtuple: 创建 具有命名字段的 tuple 子类OrderedDict: 创建 能够记住添加项目的顺序的 dict 子类Counter: 创建 计数器的 dict 子类defaultdict : 创建 存在默认值的 dict 子类deque : 创建 双端队列的 list 子类在 Python 3 中,其他相关模块:ChainMap, UserDict, UserList, UserString。 可在官方文档查看更多信息。Counter 计数counter是一个字典。 存储元素字典的键,其计数值作为字典的值。from collections import Counter

a = "aaaaabbbbcccdde"

my_counter = Counter(a)

print(my_counter)

print(my_counter.items())

print(my_counter.keys())

print(my_counter.values())

my_list = [0, 1, 0, 1, 2, 1, 1, 3, 2, 3, 2, 4]

my_counter = Counter(my_list)

print(my_counter)

# 出现次数最多的元素

print(my_counter.most_common(1))

print(my_counter.most_common(3))

print(list(my_counter.elements()))输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

dict_items([('a', 5), ('b', 4), ('c', 3), ('d', 2), ('e', 1)])

dict_keys(['a', 'b', 'c', 'd', 'e'])

dict_values([5, 4, 3, 2, 1])

Counter({1: 4, 2: 3, 0: 2, 3: 2, 4: 1})

[(1, 4)]

[(1, 4), (2, 3), (0, 2)]

[0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4]namedtuple 命名元组namedtuple 是很容易创建的,轻量级的对象类型。 它们给每个位置赋予了意义,并让代码更加易读。 它们可以在正常的元组使用的地方使用,并且添加了通过名称而不是索引来访问字段的能力。代码:from collections import namedtuple

# 创建一个具有类名为字符串和字段为字符串的 namedtuple

# 字段必须用逗号或空格分隔在给定的字符串中

Point = namedtuple('Point', 'x, y') # 创建一个元组的子类:Point。它的类名为 Point,它的字段为 x 和 y。

pt = Point(1, -4)

print(pt)

print(pt._fields)

print(type(pt))

print(pt.x, pt.y)

Person = namedtuple('Person', 'name, age')

friend = Person(name='Tom', age=25)

print(friend.name, friend.age)结果:Point(x=1, y=-4)

('x', 'y')

1 -4

Tom 25OrderedDict 有序字典 python3.7以后不建议使用它了。因为python的内置dict已经支持顺序了。 OrderedDicts 是一个简单的字典,它记住插入项目的顺序。 当迭代一个有序字典时,其项目是按照它们的键被第一次添加的顺序返回。 如果新的项目覆盖了现有的项目,则原始插入位置仍然保持不变。 它们现在已经不再需要了,因为 dict 类型获得了能够记住插入顺序的能力(从 Python 3.7 开始)。 但是还有一些差异仍然存在,例如 OrderedDict 是设计用于重新排序操作的。代码:from collections import OrderedDict

ordinary_dict = {}

ordinary_dict['a'] = 1

ordinary_dict['b'] = 2

ordinary_dict['c'] = 3

ordinary_dict['d'] = 4

ordinary_dict['e'] = 5

# 在 Python 3.7 之前是随机的

print(ordinary_dict)

ordered_dict = OrderedDict()

ordered_dict['a'] = 1

ordered_dict['b'] = 2

ordered_dict['c'] = 3

ordered_dict['d'] = 4

ordered_dict['e'] = 5

print(ordered_dict)

# 一些差异仍然存在,例如 OrderedDict 是设计用于重新排序操作的。

for k, v in ordinary_dict.items():

print(k, v)结果:{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)])

a 1

b 2

c 3

d 4

e 5defaultdict 带默认值字典defaultdict 是一个容器,它和普通的 dict 容器相似,但它只有在键不存在时才会设置默认值。 如果你不使用 defaultdict,你需要检查键是否存在,如果不存在,就设置它为你想要的值。代码:from collections import defaultdict

# 初始化为默认整数值,即 0

d = defaultdict(int)

d['yellow'] = 1

d['blue'] = 2

print(d.items())

print(d['green'])

# 初始化为默认列表值,即空列表

d = defaultdict(list)

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 5)]

for k, v in s:

d[k].append(v)

print(d.items())

print(d['green'])结果:dict_items([('yellow', 1), ('blue', 2)])

0

dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [5])])

[]deque 双端队列deque 是一个双端队列。 它可以用来在两端添加或删除元素。 deque 支持线程安全,内存效率高的在两端添加或删除元素,其执行时间为 O(1)。 deque 是一个更常用的栈和队列的衍生,其输入和输出只能在一端。代码:from collections import deque

d = deque()

# append():将元素添加到右端

d.append('a')

d.append('b')

print(d)

# appendleft(): 将元素添加到左端

d.appendleft('c')

print(d)

# pop():从右端删除并返回一个元素

print(d.pop())

print(d)

# popleft(): 从左端删除并返回一个元素

print(d.popleft())

print(d)

# clear(): 清空 deque

d.clear()

print(d)

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

# 在右端或左端添加一个序列

d.extend(['e', 'f', 'g'])

d.extendleft(['h', 'i', 'j']) # 注意,'j' 现在在左端的位置

print(d)

# count(x):返回 x 在 deque 中的个数

print(d.count('h'))

# 将 deque 向右旋转一位

d.rotate(1)

print(d)

# 将 deque 向左旋转两位

d.rotate(-2)

print(d)结果:deque(['a', 'b'])

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

b

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

c

deque(['a'])

deque([])

deque(['j', 'i', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g'])

1

deque(['g', 'j', 'i', 'h', 'a', 'b', 'c', 'd', 'e', 'f'])

deque(['i', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'j'])小节上面分享了神器collections模块的5大常用容器类型:Counter 计数namedtuple 命名元组OrderedDict 有序字典defaultdict 带默认值字典deque 双端队列熟练使用这些容器类型,在某些任务场景下将大幅提升编码效率!如对字符串的字符进行计数等。如果觉得有所收获,欢迎大家点赞、收藏,支持!pythontip 出品,Happy Coding!公众号: 夸克编程发布于 2022-04-01 10:54​赞同 10​​添加评论​分享​收藏​喜欢收起​小小张说故事历史人物解说;python编程爱好者​ 关注collections模块是Python的内建模块之一,它实现了特殊的容器数据类型,提供了Python内建的数据类型dict、list、set、和tuple的高效替代选择。一、namedtuplenamedtuple() 函数是一个工厂函数,它返回一个子类,这个子类继承自 tuple 类,并且拥有名字,这个名字就是你传给 namedtuple() 的第一个参数。这个子类的实例就像一个普通的元组,但是还提供了方便的属性访问。namedtuple是一种定义小型和不可变的数据类的简单方法。from collections import namedtuple

# 创建一个namedtuple类型User,并包含name和age两个属性。

User = namedtuple('User', ['name', 'age'])

# 创建一个User对象

user = User(name='user1', age=23)

print(user.name) # 输出:user1

print(user.age) # 输出:23二、dequedeque(双向队列)是一种来自 collections 模块的容器,它提供了从左端和右端高效、快速地添加和删除元素的功能。from collections import deque

# 创建一个deque

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

# 从右端添加元素

d.append('d') # d现在是deque(['a', 'b', 'c', 'd'])

# 从左端添加元素

d.appendleft('e') # d现在是deque(['e', 'a', 'b', 'c', 'd'])

# 从右端删除元素

d.pop() # 返回 'd', d现在是deque(['e', 'a', 'b', 'c'])

# 从左端删除元素

d.popleft() # 返回 'e', d现在是deque(['a', 'b', 'c'])三、Countercollections模块的Counter类是一个简单的计数器,例如,它可以用来统计字符的个数:from collections import Counter

c = Counter('hello world') # 从一个可迭代对象创建

print(c) # 输出 Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})Counter对象有一个有用的方法most_common(n),该方法返回计数最多的n个元素的列表,每个元素是一个元组,元组的第一个元素是元素本身,第二个元素是元素的计数。四、defaultdictdefaultdict是dict的一个子类,它接受一个工厂函数作为默认值,当查找的键不存在时,可以实例化一个值作为默认值。from collections import defaultdict

# 使用列表(list)作为default_factory,当键不存在时,返回一个空列表。

dd = defaultdict(list)

# 添加一个键值对

dd['dogs'].append('Rufus')

dd['dogs'].append('Kathrin')

dd['dogs'].append('Mr Sniffles')

print(dd['dogs']) # 输出: ['Rufus', 'Kathrin', 'Mr Sniffles']五、OrderedDictOrderedDict是dict的一个子类,它记住了元素插入的顺序。在Python 3.7之前,普通的dict并不保证键值对的顺序,而OrderedDict则按照插入的顺序排列元素。从Python 3.7开始,dict也会保持插入顺序,但是OrderedDict仍然有它的特性,如重新排列字典的顺序等。from collections import OrderedDict

d = OrderedDict()

d['first'] = 1

d['second'] = 2

d['third'] = 3

d['last'] = 4

# 输出 "first 1", "second 2", "third 3", "last 4"

for key in d:

print(key, d[key])六、结论collections模块中还包含有其他有用的工具,如ChainMap、UserDict、UserList等等,这些都是非常实用的集合类。使用和理解这些数据结构可以让我们在编程中更加得心应手,代码更加高效和清晰。上述这些是 collections 模块中最常用的一些数据结构,理解和熟练使用这些工具,可以极大提高我们编程的效率。希望这篇文章能帮助你深入理解Python中的collections模块,能够更好的使用Python进行编程。发布于 2023-06-25 08:29​赞同 2​​添加评论​分享​收藏​喜欢

Python Collections Module - GeeksforGeeks

Python Collections Module - GeeksforGeeks

Skip to content

TutorialsPython TutorialTaking Input in PythonPython OperatorsPython Data TypesPython NumbersPython StringPython ListsPython TuplesSets in PythonPython DictionaryPython Loops and Control FlowPython If ElsePython For LoopsPython While LoopsPython BreaksPython Continue StatementPython Pass StatementPython FunctionsPython OOPS ConceptPython Data StructuresPython DSALinked ListStackQueueTreeHeapHashingGraphSetsMapAdvance Data StructureSorting AlgorithmsSearching AlgorithmsPython Exception HandlingPython File HandlingPython ExercisesPython List ExercisePython String ExercisePython Tuple ExercisePython Dictionary ExercisePython Set ExercisePython Design PatternsPython Programming ExamplesPython Practice QuestionsJavaJava Programming LanguageJava TutorialData TypesVariablesOperatorsOperators in JavaArithmetic OperatorsUnary OperatorsAssignment OperatorsRelational OperatorsLogical OperatorsTernary OperatorsFlow Control in JavaFlow Controlif Statementif-else Statementif-else-if LadderContinue StatementBreak StatementReturn StatementLoops in JavaLoopsdo-while LoopFor LoopFor-each LoopMethodsStringsArraysOOPs ConceptsOOPs ConceptsClasses and ObjectsAccess ModifiersInheritanceAbstractionEncapsulationPolymorphismInterfacePackagesMultithreadingFile HandlingRegular ExpressionJava CollectionsJava CollectionsCollection ClassList InterfaceArrayListVector ClassStack ClassLinkedList ClassQueue InterfaceSet InterfaceHashSet ClassTreeSetMap InterfaceHashMap ClassHashTable ClassIteratorComparatorCollection Interview QuestionsJava 8 TutorialJava ProgramsJava Programming ExamplesJava Array ProgramsJava String ProgramsJava Date-Time ProgramsJava File Handling ProgramsJava Collection ProgramsJava JDBC ProgramsJava Apache POI ProgramsJava OpenCV ProgramsJava Interview QuestionsJava Interview QuestionsCore Java Interview Questions-FreshersJava Multithreading Interview QuestionsOOPs Interview Questions and AnswersJava ExercisesJava QuizJava QuizCore Java MCQJava ProjectsAdvance JavaSpring TutorialSpring Boot TutorialSpring Boot Interview QuestionsSpring MVC TutorialSpring MVC Interview QuestionsHibernate TutorialHibernate Interview QuestionsProgramming LanguagesCC++JavaScriptPHPR TutorialC#SQLScalaPerlGo LanguageKotlinSystem DesignSystem Design TutorialWhat is System DesignKey Terminologies in System DesignAnalysis and Architecture of SystemsScalability in System DesignDatabases in System DesignHigh Level Design or HLDLow Level Design or LLDCommunication ProtocolsWeb Servers and ProxiesCase Studies in Designing SystemsComplete System Design TutorialSoftware Design PatternsFactory PatternObserver PatternSingleton Design PatternDecorator PatternStrategy PatternAdapter PatternCommand PatternIterator PatternPrototype Design PatternAll Design PatternsSystem Design RoadmapTop 10 System Design Interview Questions and AnswersInterview CornerCompany PreparationTop TopicsPractice Company QuestionsInterview ExperiencesExperienced InterviewsInternship InterviewsCompetitive ProgrammingMultiple Choice QuizzesAptitude for PlacementsComputer Science SubjectsMathematicsOperating SystemDBMSComputer NetworksComputer Organization and ArchitectureTheory of ComputationCompiler DesignDigital LogicSoftware EngineeringDevOpsGITAWSDockerKubernetesMicrosoft Azure TutorialGoogle Cloud PlatformLinuxLinux TutorialLinux Commands A-ZLinux Commands Cheatsheet25 Basic Linux CommandsFile Mangement in LinuxFile Permission Commandschmod Commandchown Commandchgrp Commandunmask CommandLinux System AdministrationLinux File SystemLinux Shell ScriptingLinux NetworkingLinux FirewallLinux Interview QuestionsSoftware TestingSoftware Testing TutorialSoftware Testing TutorialWhat is Software TestingPrinciples of Software TestingTypes of Software TestingLevels of Software TestingAutomation TestingManual TestingTesting ToolsSoftware Testing ToolsDefect Testing ToolsCross-Browser Testing ToolsIntegration Testing ToolUnit Testing ToolsMobile Testing ToolsGUI Testing ToolSecurity Testing ToolsPenetration Testing ToolsSeleniumSelenium TutorialSelenium BasicsSelenium PythonJiraJira TutorialJIRA InstallationJIRA LoginJIRA DashboardSoftware EngineeringSoftware Engineering TutorialSoftware Development Life Cycle (SDLC)Software CharacteristicsSoftware QualityWaterfall ModelIterative Waterfall ModelSpiral ModelPrototyping ModelIncremental Process ModelInterview QuestionsSoftware Testing Interview QuestionsAutomation Testing Interview QuestionsManual Testing Interview QuestionsSoftware Engineering Interview QuestionsPenetration Testing Interview QuestionsAPI Testing Interview QuestionsPostmanPostman TutorialPostman for API DevelopmentDownload and Install PostmanAPI Testing Using PostmanGenerate HTML Report for PostmanDatabasesDBMS TutorialSQL TutorialPostgreSQL TutorialMongoDB TutorialSQL Interview QuestionsMySQL Interview QuestionsPL/SQL Interview QuestionsAndroidAndroid TutorialAndroid Studio TutorialKotlin For AndroidAndroid ProjectsAndroid Interview Questions6 Weeks of Android App DevelopmentExcelMS Excel TutorialIntroduction to MS ExcelData Analysis in ExcelBasic Excel Formulas & FunctionsData Analysis in Advanced ExcelWorkbooksStatistical FunctionsData Visualization in ExcelPivot Tables in ExcelExcel Spreadsheets in PythonBasic Excel ShortcutsMathematicsNumber SystemAlgebraLinear AlgebraTrigonometrySet TheoryStatisticsProbabilityGeometryMensurationLogarithmsCalculusCommerceBusiness StudiesAccountancyMicroeconomicsStatistics for EconomicsMacroeconomicsHuman Resource Management (HRM)ManagementIncome TaxFinanceCommerce Complete GuideSEO-Search Engine OptimizationWhat is SEOSearch Engine Optimization BasicsTypes of SEOKeyword Optimization in SEOBacklinks in SEOSEO BlogsMobile SEOSEO Complete ReferenceAptitudeAptitude Question and AnswersQuantitative AptitudeLogical ReasoningVerbal AbilityDSAData StructuresArraysMatrixStringsLinked ListSingly Linked ListDoubly Linked ListCircular Linked ListDoubly Circular Linked ListLinked List TutorialStackQueueTreeGeneric TreeBinary TreeBinary Search TreeAVL TreeB TreeB+ TreeRed Black TreeTree Data Structure TutorialHeapHashingGraphSet Data StructureMap Data StructureAdvanced Data StructureData Structures TutorialAlgorithmsAnalysis of AlgorithmsDesign and Analysis of AlgorithmsAsymptotic AnalysisAsymptotic NotationsWorst, Average and Best CasesSearching AlgorithmsLinear SearchBinary SearchSearching Algorithms TutorialSorting AlgorithmsSelection SortBubble SortInsertion SortMerge SortQuick SortHeap SortCounting SortRadix SortBucket SortSorting Algorithms TutorialGreedy AlgorithmsDynamic ProgrammingGraph AlgorithmsPattern SearchingRecursionBacktrackingDivide and ConquerMathematical AlgorithmsGeometric AlgorithmsBitwise AlgorithmsRandomized AlgorithmsBranch and BoundAlgorithms TutorialDSA TutorialPracticeAll DSA ProblemsProblem of the DayCompany Wise Coding PracticeAmazonMicrosoftFlipkartExplore AllGfG SDE SheetPractice Problems Difficulty WiseSchoolBasicEasyMediumHardLanguage Wise Coding PracticeCPPJavaPythonCurated DSA ListsBeginner's DSA SheetTop 50 Array ProblemsTop 50 String ProblemsTop 50 DP ProblemsTop 50 Graph ProblemsTop 50 Tree ProblemsCompetitive ProgrammingCompany Wise SDE SheetsFacebook SDE SheetAmazon SDE SheetApple SDE SheetNetflix SDE SheetGoogle SDE SheetDSA Cheat SheetsSDE SheetDSA Sheet for BeginnersFAANG Coding SheetProduct-Based Coding SheetCompany-Wise Preparation SheetTop Interview QuestionsTop 100 DSA Interview Questions Topic-wisePuzzlesAll PuzzlesTop 100 Puzzles Asked In InterviewsTop 20 Puzzles Commonly Asked During SDE InterviewsData SciencePython TutorialR TutorialMachine LearningData Science using PythonData Science using RData Science PackagesPandas TutorialNumPy TutorialData VisualizationPython Data Visualization TutorialData Visualization with RData AnalysisData Analysis with PythonData Analysis with RDeep LearningNLP TutorialWeb TechHTML TutorialCSS TutorialJavaScript TutorialPHP TutorialReactJS TutorialNodeJS TutorialAngularJS TutorialBootstrap TutorialWeb Development Using PythonDjangoGetting started with DjangoCreate an App in DjangoViews In DjangoDjango TemplatesDjango URL patternsDjango Admin InterfaceDjango ModelsMySQL Databased with DjangoDjango CRUDDjango FormsDjango Static FileProjects for BeginnersDjango TutorialFlaskWeb Development Using FlaskFlask App RoutingURL building in FlaskFlask TemplatesTemplating With Jinja2 in FlaskFlask ModelDatabase with Flask SQL AlchemyAuthentication with FlaskWTForms in FlaskStatic files in FlaskPython Flask ProjectsFlask Interview QuestionsFrontend ProjectsBuilding a Survey Form using HTML and CSSFood delivery system using HTML and CSSToDo webapp using DjangoBuilding Blog CMSAdd Pagination in DjangoTailwind CSS with DjangoDjango with ReactjsPostmanGithubJSON TutorialTypeScript TutorialWordpress TutorialWeb DesignWeb BrowsersGoogle ChromeMozilla FirefoxApple SafariMicrosoft EdgeTorCheat SheetsHTML Cheat SheetCSS Cheat SheetJavaScript Cheat SheetReact Cheat SheetAngular Cheat SheetjQuery Cheat SheetBootstrap Cheat SheetJavaScript ProjectsLearn Complete Web DevelopmentFile FormatsCoursesCoding for EveryoneDSA to DevelopmentMachine Learning and Data ScienceDSA CoursesData Structure & Algorithm(C++/JAVA)Data Structure & Algorithm(Python)Data Structure & Algorithm(JavaScript)Programming LanguagesCPPJavaPythonJavaScriptC

Home

Saved Videos

Courses

Data Structures and Algorithms

DSA Tutorial

Data Structures Tutorial

Algorithms Tutorial

Top 100 DSA Interview Questions

DSA-Roadmap[Basic-to-Advanced]

ML & Data Science

Learn Python

Data Science Tutorial

Machine Learning Tutorial

Deep Learning Tutorial

NLP Tutorial

Computer Vision Tutorial

Web Development

HTML Tutorial

CSS Tutorial

JavaScript Tutorial

ReactJS Tutorial

NodeJS Tutorial

Languages

C

C++

Java

R Tutorial

Golang

Interview Corner

Company Interview Corner

Experienced Interviews

Internship Experiences

Practice Company Questions

Competitive Programming

CS Subjects

Operating Systems

DBMS

Computer Networks

Software Engineering

Software Testing

Jobs

Get Hired: Apply for Jobs

Job-a-thon: Hiring Challenge

Corporate Hiring Solutions

Practice

All DSA Problems

Problem of the Day

GFG SDE Sheet

Beginner's DSA Sheet

Love Babbar Sheet

Top 50 Array Problems

Top 50 String Problems

Top 50 DP Problems

Top 50 Graph Problems

Top 50 Tree Problems

Contests

World Cup Hack-A-Thon

GFG Weekly Coding Contest

Job-A-Thon: Hiring Challenge

BiWizard School Contest

All Contests and Events

GBlog

Puzzles

What's New ?

Change Language

Free Python 3 TutorialData TypesControl FlowFunctionsListStringSetTupleDictionaryOopsException HandlingPython ProgramsPython ProjectsPython Interview QuestionsPython MCQNumPyPandasPython DatabaseData Science With PythonMachine Learning with PythonDjangoFlaskR

Open In App

Related Articles

Solve Coding ProblemsPython Collections ModuleNamedtuple in PythonDeque in PythonChainMap in PythonPython | Counter Objects | elements()OrderedDict in PythonDefaultdict in PythonCollections.UserDict in PythonCollections.UserList in PythonCollections.UserString in Python

Solve Coding ProblemsPython Collections ModuleNamedtuple in PythonDeque in PythonChainMap in PythonPython | Counter Objects | elements()OrderedDict in PythonDefaultdict in PythonCollections.UserDict in PythonCollections.UserList in PythonCollections.UserString in Python

Python Collections Module

Improve

Improve

Improve

Like Article

Like

Save Article

Save

Share

Report issue

Report

The collection Module in Python provides different types of containers. A Container is an object that is used to store different objects and provide a way to access the contained objects and iterate over them. Some of the built-in containers are Tuple, List, Dictionary, etc. In this article, we will discuss the different containers provided by the collections module.

Table of Content:

CountersOrderedDictDefaultDictChainMapNamedTupleDeQueUserDictUserListUserStringCounters

A counter is a sub-class of the dictionary. It is used to keep the count of the elements in an iterable in the form of an unordered dictionary where the key represents the element in the iterable and value represents the count of that element in the iterable.

Note: It is equivalent to bag or multiset of other languages.

Syntax:

class collections.Counter([iterable-or-mapping])Initializing Counter Objects

The counter object can be initialized using the counter() function and this function can be called in one of the following ways:

With a sequence of itemsWith a dictionary containing keys and countsWith keyword arguments mapping string names to counts

Example:

Python3

# A Python program to show different  # ways to create Counter  from collections import Counter      # With sequence of items   print(Counter(['B','B','A','B','C','A','B',                'B','A','C']))     # with dictionary  print(Counter({'A':3, 'B':5, 'C':2}))     # with keyword arguments  print(Counter(A=3, B=5, C=2))

Output:

Counter({'B': 5, 'A': 3, 'C': 2})

Counter({'B': 5, 'A': 3, 'C': 2})

Counter({'B': 5, 'A': 3, 'C': 2})

Note: For more information, refer  Counters in Python.

OrderedDict

An OrderedDict is also a sub-class of dictionary but unlike dictionary, it remembers the order in which the keys were inserted. 

Syntax:

class collections.OrderDict()

Example:

Python3

# A Python program to demonstrate working # of OrderedDict    from collections import OrderedDict      print("This is a Dict:\n")  d = {}  d['a'] = 1d['b'] = 2d['c'] = 3d['d'] = 4    for key, value in d.items():      print(key, value)      print("\nThis is an Ordered Dict:\n")  od = OrderedDict()  od['a'] = 1od['b'] = 2od['c'] = 3od['d'] = 4    for key, value in od.items():      print(key, value)

Output:

This is a Dict:

a 1

b 2

c 3

d 4

This is an Ordered Dict:

a 1

b 2

c 3

d 4

While deleting and re-inserting the same key will push the key to the last to maintain the order of insertion of the key.

Example:

Python3

# A Python program to demonstrate working # of OrderedDict    from collections import OrderedDict      od = OrderedDict()  od['a'] = 1od['b'] = 2od['c'] = 3od['d'] = 4    print('Before Deleting') for key, value in od.items():      print(key, value)        # deleting element od.pop('a')   # Re-inserting the same od['a'] = 1  print('\nAfter re-inserting') for key, value in od.items():      print(key, value)

Output:

Before Deleting

a 1

b 2

c 3

d 4

After re-inserting

b 2

c 3

d 4

a 1

Note: for more information, refer OrderedDict in Python

DefaultDict

A DefaultDict is also a sub-class to dictionary. It is used to provide some default values for the key that does not exist and never raises a KeyError.

Syntax:

class collections.defaultdict(default_factory)

default_factory is a function that provides the default value for the dictionary created. If this parameter is absent then the KeyError is raised.

Initializing DefaultDict Objects

DefaultDict objects can be initialized using DefaultDict() method by passing the data type as an argument.

Example:

Python3

# Python program to demonstrate  # defaultdict            from collections import defaultdict            # Defining the dict  d = defaultdict(int)       L = [1, 2, 3, 4, 2, 4, 1, 2]       # Iterate through the list  # for keeping the count  for i in L:               # The default value is 0      # so there is no need to       # enter the key first      d[i] += 1         print(d)

Output:

defaultdict(, {1: 2, 2: 3, 3: 1, 4: 2})

Example 2:

Python3

# Python program to demonstrate  # defaultdict          from collections import defaultdict          # Defining a dict  d = defaultdict(list)      for i in range(5):      d[i].append(i)          print("Dictionary with values as list:")  print(d)

Output:

Dictionary with values as list: defaultdict(, {0: [0], 1: [1], 2: [2], 3: [3], 4: [4]})

Note: For more information, refer Defaultdict in Python

ChainMap

A ChainMap encapsulates many dictionaries into a single unit and returns a list of dictionaries.

Syntax:

class collections.ChainMap(dict1, dict2)

Example:

Python3

# Python program to demonstrate  # ChainMap            from collections import ChainMap            d1 = {'a': 1, 'b': 2} d2 = {'c': 3, 'd': 4} d3 = {'e': 5, 'f': 6}   # Defining the chainmap  c = ChainMap(d1, d2, d3)       print(c)

Output:

ChainMap({'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 5, 'f': 6})Accessing Keys and Values from ChainMap

Values from ChainMap can be accessed using the key name. They can also be accessed by using the keys() and values() method.

Example:

Python3

# Python program to demonstrate  # ChainMap            from collections import ChainMap            d1 = {'a': 1, 'b': 2} d2 = {'c': 3, 'd': 4} d3 = {'e': 5, 'f': 6}   # Defining the chainmap  c = ChainMap(d1, d2, d3)       # Accessing Values using key name print(c['a'])   # Accessing values using values() # method print(c.values())   # Accessing keys using keys() # method print(c.keys())

Output:

1 ValuesView(ChainMap({‘a’: 1, ‘b’: 2}, {‘c’: 3, ‘d’: 4}, {‘e’: 5, ‘f’: 6})) KeysView(ChainMap({‘a’: 1, ‘b’: 2}, {‘c’: 3, ‘d’: 4}, {‘e’: 5, ‘f’: 6}))

Adding new dictionary

A new dictionary can be added by using the new_child() method. The newly added dictionary is added at the beginning of the ChainMap.

Example:

Python3

# Python code to demonstrate ChainMap and  # new_child()      import collections      # initializing dictionaries  dic1 = { 'a' : 1, 'b' : 2 }  dic2 = { 'b' : 3, 'c' : 4 }  dic3 = { 'f' : 5 }      # initializing ChainMap  chain = collections.ChainMap(dic1, dic2)      # printing chainMap  print ("All the ChainMap contents are : ")  print (chain)      # using new_child() to add new dictionary  chain1 = chain.new_child(dic3)      # printing chainMap print ("Displaying new ChainMap : ")  print (chain1)

Output:

All the ChainMap contents are :

ChainMap({'a': 1, 'b': 2}, {'b': 3, 'c': 4})

Displaying new ChainMap :

ChainMap({'f': 5}, {'a': 1, 'b': 2}, {'b': 3, 'c': 4})

Note: For more information, refer ChainMap in Python

NamedTuple

A NamedTuple returns a tuple object with names for each position which the ordinary tuples lack. For example, consider a tuple names student where the first element represents fname, second represents lname and the third element represents the DOB. Suppose for calling fname instead of remembering the index position you can actually call the element by using the fname argument, then it will be really easy for accessing tuples element. This functionality is provided by the NamedTuple.

Syntax:

class collections.namedtuple(typename, field_names)

Example:

Python3

# Python code to demonstrate namedtuple()     from collections import namedtuple     # Declaring namedtuple()  Student = namedtuple('Student',['name','age','DOB'])      # Adding values  S = Student('Nandini','19','2541997')      # Access using index  print ("The Student age using index is : ",end ="")  print (S[1])      # Access using name   print ("The Student name using keyname is : ",end ="")  print (S.name)

Output:

The Student age using index is : 19

The Student name using keyname is : NandiniConversion Operations 

1. _make(): This function is used to return a namedtuple() from the iterable passed as argument.

2. _asdict(): This function returns the OrderedDict() as constructed from the mapped values of namedtuple().

Example:

Python3

# Python code to demonstrate namedtuple() and  # _make(), _asdict()       from collections import namedtuple     # Declaring namedtuple()  Student = namedtuple('Student',['name','age','DOB'])      # Adding values  S = Student('Nandini','19','2541997')      # initializing iterable   li = ['Manjeet', '19', '411997' ]      # initializing dict  di = { 'name' : "Nikhil", 'age' : 19 , 'DOB' : '1391997' }      # using _make() to return namedtuple()  print ("The namedtuple instance using iterable is  : ")  print (Student._make(li))      # using _asdict() to return an OrderedDict()  print ("The OrderedDict instance using namedtuple is  : ")  print (S._asdict())

Output:

The namedtuple instance using iterable is :

Student(name='Manjeet', age='19', DOB='411997')

The OrderedDict instance using namedtuple is :

OrderedDict([('name', 'Nandini'), ('age', '19'), ('DOB', '2541997')])

Note: For more  information, refer NamedTuple in Python

DequeDeque (Doubly Ended Queue) is the optimized list for quicker append and pop operations from both sides of the container. It provides O(1) time complexity for append and pop operations as compared to list with O(n) time complexity.

Syntax:

class collections.deque(list)

This function takes the list as an argument.

Example:

Python3

# Python code to demonstrate deque       from collections import deque     # Declaring deque queue = deque(['name','age','DOB'])      print(queue)

Output:

deque(['name', 'age', 'DOB'])Inserting Elements

Elements in deque can be inserted from both ends. To insert the elements from right append() method is used and to insert the elements from the left appendleft() method is used.

Example:

Python3

# Python code to demonstrate working of   # append(), appendleft()       from collections import deque      # initializing deque  de = deque([1,2,3])      # using append() to insert element at right end   # inserts 4 at the end of deque  de.append(4)      # printing modified deque  print ("The deque after appending at right is : ")  print (de)      # using appendleft() to insert element at left end   # inserts 6 at the beginning of deque  de.appendleft(6)      # printing modified deque  print ("The deque after appending at left is : ")  print (de)

Output:

The deque after appending at right is :

deque([1, 2, 3, 4])

The deque after appending at left is :

deque([6, 1, 2, 3, 4])Removing Elements

Elements can also be removed from the deque from both the ends. To remove elements from right use pop() method and to remove elements from the left use popleft() method.

Example:

Python3

# Python code to demonstrate working of   # pop(), and popleft()    from collections import deque   # initializing deque  de = deque([6, 1, 2, 3, 4])   # using pop() to delete element from right end   # deletes 4 from the right end of deque  de.pop()      # printing modified deque  print ("The deque after deleting from right is : ")  print (de)      # using popleft() to delete element from left end   # deletes 6 from the left end of deque  de.popleft()      # printing modified deque  print ("The deque after deleting from left is : ")  print (de)

Output:

The deque after deleting from right is :

deque([6, 1, 2, 3])

The deque after deleting from left is :

deque([1, 2, 3])

Note: For more information, refer Deque in Python.

UserDict

UserDict is a dictionary-like container that acts as a wrapper around the dictionary objects. This container is used when someone wants to create their own dictionary with some modified or new functionality. 

Syntax:

class collections.UserDict([initialdata])

Example:

Python3

# Python program to demonstrate  # userdict           from collections import UserDict           # Creating a Dictionary where  # deletion is not allowed  class MyDict(UserDict):              # Function to stop deletion      # from dictionary      def __del__(self):          raise RuntimeError("Deletion not allowed")                  # Function to stop pop from       # dictionary      def pop(self, s = None):          raise RuntimeError("Deletion not allowed")                  # Function to stop popitem       # from Dictionary      def popitem(self, s = None):          raise RuntimeError("Deletion not allowed")          # Driver's code  d = MyDict({'a':1,      'b': 2,      'c': 3})     d.pop(1)

Output:

Traceback (most recent call last):

File "/home/f8db849e4cf1e58177983b2b6023c1a3.py", line 32, in

d.pop(1)

File "/home/f8db849e4cf1e58177983b2b6023c1a3.py", line 20, in pop

raise RuntimeError("Deletion not allowed")

RuntimeError: Deletion not allowed

Exception ignored in:

Traceback (most recent call last):

File "/home/f8db849e4cf1e58177983b2b6023c1a3.py", line 15, in __del__

RuntimeError: Deletion not allowed

Note: For more information, refer UserDict in Python

UserListUserList is a list like container that acts as a wrapper around the list objects. This is useful when someone wants to create their own list with some modified or additional functionality.

Syntax:

class collections.UserList([list])

Example:

Python3

# Python program to demonstrate  # userlist           from collections import UserList           # Creating a List where  # deletion is not allowed  class MyList(UserList):              # Function to stop deletion      # from List      def remove(self, s = None):          raise RuntimeError("Deletion not allowed")                  # Function to stop pop from       # List      def pop(self, s = None):          raise RuntimeError("Deletion not allowed")          # Driver's code  L = MyList([1, 2, 3, 4])      print("Original List")      # Inserting to List"  L.append(5)  print("After Insertion")  print(L)      # Deleting From List  L.remove()

Output:

Original List

After Insertion

[1, 2, 3, 4, 5]Traceback (most recent call last):

File "/home/c90487eefa7474c0566435269f50a52a.py", line 33, in

L.remove()

File "/home/c90487eefa7474c0566435269f50a52a.py", line 15, in remove

raise RuntimeError("Deletion not allowed")

RuntimeError: Deletion not allowed

Note: For more information, refer UserList in Python

UserStringUserString is a string like container and just like UserDict and UserList it acts as a wrapper around string objects. It is used when someone wants to create their own strings with some modified or additional functionality. 

Syntax:

class collections.UserString(seq)

Example:

Python3

# Python program to demonstrate  # userstring           from collections import UserString           # Creating a Mutable String  class Mystring(UserString):              # Function to append to      # string      def append(self, s):          self.data += s                  # Function to remove from       # string      def remove(self, s):          self.data = self.data.replace(s, "")          # Driver's code  s1 = Mystring("Geeks")  print("Original String:", s1.data)      # Appending to string  s1.append("s")  print("String After Appending:", s1.data)      # Removing from string  s1.remove("e")  print("String after Removing:", s1.data)

Output:

Original String: Geeks

String After Appending: Geekss

String after Removing: Gkss

Note: For more information, refer UserString in Python

Last Updated :

08 Jun, 2023

Like Article

Save Article

Next

Namedtuple in Python

Share your thoughts in the comments

Add Your Comment

Please Login to comment...

Similar Reads

Count frequencies of all elements in array in Python using collections module

Os Module Vs. Sys Module In Python

Python - Distance between collections of inputs

Collections.UserList in Python

Collections.UserDict in Python

Collections.UserString in Python

Python - Queue.LIFOQueue vs Collections.Deque

Difference between queue.queue vs collections.deque in Python

Anagram checking in Python using collections.Counter()

Python Importerror: Cannot Import Name Mapping From Collections

Complete Tutorials

Python Crash Course

Python API Tutorial: Getting Started with APIs

Advanced Python Tutorials

Python Automation Tutorial

OpenAI Python API - Complete Guide

Like

N

nikhilaggarwal3

Follow

Article Tags :

Python collections-module

Python

Practice Tags :

python

Additional Information

Current difficulty :

Easy

Vote for difficulty :

Easy

Normal

Medium

Hard

Expert

Improved By :

saurabh1990arorvarshagumber28sooda367kapoorsagar226diyaroy22baurzhankonurbayev

Trending in News

View More

What is Bland Turbo and How to Use This Conversational AI?What is Perchance AI and How to Use This Text-to-Image AI Tool?Fintech startup CredAble scores $10 Mn in new roundGoogle Gemini Advanced vs ChatGPT Plus: Which AI assistant is best for you? Dev Scripter 2024 - Biggest Technical Writing Event By GeeksforGeeks

Explore More

A-143, 9th Floor, Sovereign Corporate Tower, Sector-136, Noida, Uttar Pradesh - 201305

CompanyAbout UsLegalCareersIn MediaContact UsAdvertise with usGFG Corporate SolutionPlacement Training ProgramExploreJob-A-Thon Hiring ChallengeHack-A-ThonGfG Weekly ContestOffline Classes (Delhi/NCR)DSA in JAVA/C++Master System DesignMaster CPGeeksforGeeks VideosGeeks CommunityLanguagesPythonJavaC++PHPGoLangSQLR LanguageAndroid TutorialTutorials ArchiveDSAData StructuresAlgorithmsDSA for BeginnersBasic DSA ProblemsDSA RoadmapTop 100 DSA Interview ProblemsDSA Roadmap by Sandeep JainAll Cheat SheetsData Science & MLData Science With PythonData Science For BeginnerMachine Learning TutorialML MathsData Visualisation TutorialPandas TutorialNumPy TutorialNLP TutorialDeep Learning TutorialHTML & CSSHTMLCSSWeb TemplatesCSS FrameworksBootstrapTailwind CSSSASSLESSWeb DesignPythonPython Programming ExamplesDjango TutorialPython ProjectsPython TkinterWeb ScrapingOpenCV Python TutorialPython Interview QuestionComputer ScienceGATE CS NotesOperating SystemsComputer NetworkDatabase Management SystemSoftware EngineeringDigital Logic DesignEngineering MathsDevOpsGitAWSDockerKubernetesAzureGCPDevOps RoadmapCompetitive ProgrammingTop DS or Algo for CPTop 50 TreeTop 50 GraphTop 50 ArrayTop 50 StringTop 50 DPTop 15 Websites for CPSystem DesignHigh Level DesignLow Level DesignUML DiagramsInterview GuideDesign PatternsOOADSystem Design BootcampInterview QuestionsJavaScriptJavaScript ExamplesTypeScriptReactJSNextJSAngularJSNodeJSLodashWeb BrowserNCERT SolutionsClass 12Class 11Class 10Class 9Class 8Complete Study MaterialSchool SubjectsMathematicsPhysicsChemistryBiologySocial ScienceEnglish GrammarCommerceAccountancyBusiness StudiesEconomicsManagementHR ManagementFinanceIncome TaxUPSC Study MaterialPolity NotesGeography NotesHistory NotesScience and Technology NotesEconomy NotesEthics NotesPrevious Year PapersSSC/ BANKINGSSC CGL SyllabusSBI PO SyllabusSBI Clerk SyllabusIBPS PO SyllabusIBPS Clerk SyllabusSSC CGL Practice PapersCollegesIndian Colleges Admission & Campus ExperiencesList of Central Universities - In IndiaColleges in Delhi UniversityIIT CollegesNIT CollegesIIIT CollegesCompaniesMETA Owned CompaniesAlphabhet Owned CompaniesTATA Group Owned CompaniesReliance Owned CompaniesFintech CompaniesEdTech CompaniesPreparation CornerCompany-Wise Recruitment ProcessResume TemplatesAptitude PreparationPuzzlesCompany-Wise PreparationExamsJEE MainsJEE AdvancedGATE CSNEETUGC NETMore TutorialsSoftware DevelopmentSoftware TestingProduct ManagementSAPSEO - Search Engine OptimizationLinuxExcelFree Online ToolsTyping TestImage EditorCode FormattersCode ConvertersCurrency ConverterRandom Number GeneratorRandom Password GeneratorWrite & EarnWrite an ArticleImprove an ArticlePick Topics to WriteShare your ExperiencesInternships

@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved

We use cookies to ensure you have the best browsing experience on our website. By using our site, you

acknowledge that you have read and understood our

Cookie Policy &

Privacy Policy

Got It !

Improvement

Please go through our recently updated Improvement Guidelines before submitting any improvements.

This article is being improved by another user right now. You can suggest the changes for now and it will be under the article's discussion tab.

You will be notified via email once the article is available for improvement.

Thank you for your valuable feedback!

Suggest changes

Please go through our recently updated Improvement Guidelines before submitting any improvements.

Suggest Changes

Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.

Create Improvement

Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.

Suggest Changes

Suggestion[CharLimit:2000]

Create Improvement

What kind of Experience do you want to share?

Interview Experiences

Admission Experiences

Engineering Exam Experiences

Work Experiences

Campus Experiences

Add Other Experiences