首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >集合Collections

集合Collections

作者头像
Helloted
发布2022-06-07 13:31:52
发布2022-06-07 13:31:52
43700
举报
文章被收录于专栏:HellotedHelloted
运行总次数:0

Python附带一个模块包含了许多称为集合的容器数据类型。

  • defaultdict
  • OrderedDict
  • counter
  • deque
  • namedtuple
  • enum.Enum (outside of the module; Python 3.4+)
defaultdict

我个人使用defaultdict相当多。 与dict不同,defaultdict不需要检查一个键是否存在。 所以我们可以这样做:

代码语言:javascript
代码运行次数:0
运行
复制
from collections import defaultdict

colours = (
    ('Yasoob', 'Yellow'),
    ('Ali', 'Blue'),
    ('Arham', 'Green'),
    ('Ali', 'Black'),
    ('Yasoob', 'Red'),
    ('Ahmed', 'Silver'),
)

favourite_colours = defaultdict(list)

for name, colour in colours:
    favourite_colours[name].append(colour)

print(favourite_colours)

# output
# defaultdict(<type 'list'>,
#    {'Arham': ['Green'],
#     'Yasoob': ['Yellow', 'Red'],
#     'Ahmed': ['Silver'],
#     'Ali': ['Blue', 'Black']
# })

另外一个非常重要的用法是在字典中追加嵌套list。 如果一个键不在字典中,那么会产生一个KeyError。 defaultdict允许我们以一种聪明的方式绕开这个问题。 首先让我分享一个使用dict的例子,它引发了KeyError,然后我将使用defaultdict来分享一个解决方案。

问题:

代码语言:javascript
代码运行次数:0
运行
复制
some_dict = {}
some_dict['colours']['favourite'] = "yellow"
# Raises KeyError: 'colours'

解决方案:

代码语言:javascript
代码运行次数:0
运行
复制
import collections
tree = lambda: collections.defaultdict(tree)
some_dict = tree()
some_dict['colours']['favourite'] = "yellow"
# Works fine

你可以打印 some_dictjson.dumps:

代码语言:javascript
代码运行次数:0
运行
复制
import json
print(json.dumps(some_dict))
# Output: {"colours": {"favourite": "yellow"}}
OrderedDict

OrderedDict保持其键值按照最初插入的顺序排序。 覆盖现有key的值不会改变该键值的位置。 但是,删除并重新插入键值会将该键值移到字典的末尾。

无顺序:

代码语言:javascript
代码运行次数:0
运行
复制
colours =  {"Red" : 198, "Green" : 170, "Blue" : 160}
for key, value in colours.items():
    print(key, value)
# Output:
#   Green 170
#   Blue 160
#   Red 198
# Entries are retrieved in an unpredictable order

有顺序

代码语言:javascript
代码运行次数:0
运行
复制
from collections import OrderedDict

colours = OrderedDict([("Red", 198), ("Green", 170), ("Blue", 160)])
for key, value in colours.items():
    print(key, value)
# Output:
#   Red 198
#   Green 170
#   Blue 160
# Insertion order is preserved
counter

counter计数器允许我们计算特定项目的出现次数。 例如,它可以用来计算个人最喜欢的颜色的数量:

代码语言:javascript
代码运行次数:0
运行
复制
from collections import Counter

colours = (
    ('Yasoob', 'Yellow'),
    ('Ali', 'Blue'),
    ('Arham', 'Green'),
    ('Ali', 'Black'),
    ('Yasoob', 'Red'),
    ('Ahmed', 'Silver'),
)

favs = Counter(name for name, colour in colours)
print(favs)
# Output: Counter({
#    'Yasoob': 2,
#    'Ali': 2,
#    'Arham': 1,
#    'Ahmed': 1
# })

同样可以用这个来计算一个文件中的最大相同行数

代码语言:javascript
代码运行次数:0
运行
复制
with open('filename', 'rb') as f:
    line_count = Counter(f)
print(line_count)

deque为您提供了一个双端队列,这意味着您可以从队列的任意一侧追加和删除元素。

代码语言:javascript
代码运行次数:0
运行
复制
from collections import deque

d = deque()
d.append('1')
d.append('2')
d.append('3')

print(len(d))
# Output: 3

print(d[0])
# Output: '1'

print(d[-1])
# Output: '3'

你可以在两端pop值:

代码语言:javascript
代码运行次数:0
运行
复制
d = deque(range(5))
print(len(d))
# Output: 5

d.popleft()
# Output: 0

d.pop()
# Output: 4

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

你可以限制队列的最大长度。如果这样做当我们接收超出最大长度时,队里会在另外一端pop出。

代码语言:javascript
代码运行次数:0
运行
复制
d = deque(maxlen=30)

d = deque([1,2,3,4,5])
d.extendleft([0])
d.extend([6,7,8])
print(d)
# Output: deque([0, 1, 2, 3, 4, 5, 6, 7, 8])
namedtuple

你可能已经熟悉元组了。 一个元组基本上是一个不可变的list,它允许你存储由逗号分隔的一系列值。 他们就像list,但有几个关键的区别。 主要的一点是,不像list,你不能重新分配元组中的项目。 为了访问元组中的值,可以使用如下的整数索引:

代码语言:javascript
代码运行次数:0
运行
复制
man = ('Ali', 30)
print(man[0])
# Output: Ali

那么现在是什么namedtuple? 他们把元组变成方便的容器来完成简单的任务。 使用namedtuples,您不必使用整数索引来访问元组的成员。 你可以把namedtuple看作字典,但不同于字典,它们是不可变的。

代码语言:javascript
代码运行次数:0
运行
复制
from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")

print(perry)
# Output: Animal(name='perry', age=31, type='cat')

print(perry.name)
# Output: 'perry'

现在你可以看到,我们可以通过使用一个名称来访问元组的成员。让我们再解析一下。 一个命名的元组有两个必需的参数。 它们是元组的名称和元组的field_names。 在上面的例子中,我们的元组名是’Animal’,而元组的field_names是’name’,’age’和’type’。 Namedtuple使你的元组自己生成文档。 快速浏览一下你的代码就可以很容易的理解到底发生了什么。 而且由于您不必使用整数索引来访问元组的成员,因此可以更容易地维护您的代码。 此外,由于namedtuple实例没有每个实例字典,所以它们是轻量级的,并且不需要比常规元组更多的内存。 这使得它们比字典更快。 但是,请记住,与元组一样,namedtuples中的属性是不可变的。

这意味着这是下面这是行不通的:

代码语言:javascript
代码运行次数:0
运行
复制
from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")
perry.age = 42

# Output: Traceback (most recent call last):
#            File "", line 1, in
#         AttributeError: can't set attribute

你同样可以用index来访问:

代码语言:javascript
代码运行次数:0
运行
复制
from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")
print(perry[0])
# Output: perry

你可以把namedtuple转化成字典

代码语言:javascript
代码运行次数:0
运行
复制
from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="Perry", age=31, type="cat")
print(perry._asdict())
# Output: OrderedDict([('name', 'Perry'), ('age', 31), ...
enum.Enum(Python 3.4+)
代码语言:javascript
代码运行次数:0
运行
复制
from collections import namedtuple
from enum import Enum

class Species(Enum):
    cat = 1
    dog = 2
    horse = 3
    aardvark = 4
    butterfly = 5
    owl = 6
    platypus = 7
    dragon = 8
    unicorn = 9
    # The list goes on and on...

    # But we don't really care about age, so we can use an alias.
    kitten = 1
    puppy = 2

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="Perry", age=31, type=Species.cat)
drogon = Animal(name="Drogon", age=4, type=Species.dragon)
tom = Animal(name="Tom", age=75, type=Species.cat)
charlie = Animal(name="Charlie", age=2, type=Species.kitten)

# And now, some tests.
>>> charlie.type == tom.type
True
>>> charlie.type
<Species.cat: 1>

有三个方法去访问enumeration成员

代码语言:javascript
代码运行次数:0
运行
复制
Species(1)
Species['cat']
Species.cat
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • defaultdict
  • OrderedDict
  • counter
  • namedtuple
  • enum.Enum(Python 3.4+)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档