资讯专栏INFORMATION COLUMN

不可不知的python模块--collections

韩冰 / 459人阅读

摘要:原生的也可以从头部添加和取出对象就像这样但是值得注意的是,对象的这两种用法的时间复杂度是,也就是说随着元素数量的增加耗时呈线性上升。

基本介绍

Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型:

namedtuple(): 生成可以使用名字来访问元素内容的tuple子类

deque: 双端队列,可以快速的从另外一侧追加和推出对象

Counter: 计数器,主要用来计数

OrderedDict: 有序字典

defaultdict: 带有默认值的字典

namedtuple()

namedtuple主要用来产生可以使用名称来访问元素的数据对象,通常用来增强代码的可读性, 在访问一些tuple类型的数据时尤其好用。
例子1:

import collections

coordinate = collections.namedtuple("Coordinate", ["x", "y"])
co = coordinate(10,20)
print(type(co))
print(co)
print(co.x, co.y)
print(co[0], co[1])
co = coordinate._make([100, 200])
print(co)
print(co.x, co.y)
co = co._replace(x=30)
print(co)
print(co.x, co.y)

运行:


Coordinate(x=10, y=20)
10 20
10 20
Coordinate(x=100, y=200)
100 200
Coordinate(x=30, y=200)
30 200

例子2:

websites = [
    ("Sohu", "http://www.sohu.com/", u"张朝阳"),
    ("Sina", "http://www.sina.com.cn/", u"王志东"),
    ("163", "http://www.163.com/", u"丁磊")
]

Website = collections.namedtuple("Website", ["name", "url", "founder"])

for website in websites:
    website = Website._make(website)
    print(website)

运行:

Website(name="Sohu", url="http://www.sohu.com/", founder="张朝阳")
Website(name="Sina", url="http://www.sina.com.cn/", founder="王志东")
Website(name="163", url="http://www.163.com/", founder="丁磊")

例子3(一摞有序的纸牌):

import collections
Card = collections.namedtuple("Card", ["rank", "suit"])


class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list("JQKA")
    suits = "spades diamonds clubs hearts".split()

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, position):
        return self._cards[position]

beer_card = Card("7", "diamonds")
print(beer_card)

deck = FrenchDeck()
print(len(deck))

print(deck._cards)
print(deck[0])
print(deck[-1])

from random import choice
print(choice(deck))

print(deck[:3])
print(deck[12::13])     # 先抽出索引是 12 的那张牌,然后每隔 13 张牌拿 1 张

for card in deck:
    print(card)

for card in reversed(deck):
    print(card)
deque

deque其实是 double-ended queue 的缩写,翻译过来就是双端队列,它最大的好处就是实现了从队列 头部快速增加和取出对象: .popleft(), .appendleft() 。

原生的list也可以从头部添加和取出对象?就像这样:

l.insert(0, v)
l.pop(0)

但是值得注意的是,list对象的这两种用法的时间复杂度是 O(n) ,也就是说随着元素数量的增加耗时呈 线性上升。而使用deque对象则是 O(1) 的复杂度,所以当你的代码有这样的需求的时候, 一定要记得使用deque。

作为一个双端队列,deque还提供了一些其他的好用方法,比如 rotate 等。

例子:

# -*- coding: utf-8 -*-
"""
下面这个是一个有趣的例子,主要使用了deque的rotate方法来实现了一个无限循环
的加载动画
"""
import sys
import time
from collections import deque

fancy_loading = deque(">--------------------")

while True:
    print "
%s" % "".join(fancy_loading),
    fancy_loading.rotate(1)
    sys.stdout.flush()
    time.sleep(0.08)

运行:

# 一个无尽循环的跑马灯
------------->-------
Counter

计数器是一个非常常用的功能需求,collections也贴心的为你提供了这个功能。

例子:

# -*- coding: utf-8 -*-
"""
下面这个例子就是使用Counter模块统计一段句子里面所有字符出现次数
"""
from collections import Counter

s = """A Counter is a dict subclass for counting hashable objects. It is an unordered 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.""".lower()

c = Counter(s)
# 获取出现频率最高的5个字符
print c.most_common(5)

运行:

[(" ", 54), ("e", 32), ("s", 25), ("a", 24), ("t", 24)]
OrderedDict

在Python中,dict这个数据结构由于hash的特性,是无序的,这在有的时候会给我们带来一些麻烦, 幸运的是,collections模块为我们提供了OrderedDict,当你要获得一个有序的字典对象时,用它就对了。

例子:

# -*- coding: utf-8 -*-
from collections import OrderedDict

items = (
    ("A", 1),
    ("B", 2),
    ("C", 3)
)

regular_dict = dict(items)
ordered_dict = OrderedDict(items)

print "Regular Dict:"
for k, v in regular_dict.items():
    print k, v

print "Ordered Dict:"
for k, v in ordered_dict.items():
    print k, v

运行:

Regular Dict:
A 1
C 3
B 2
Ordered Dict:
A 1
B 2
C 3
defaultdict

我们都知道,在使用Python原生的数据结构dict的时候,如果用 d[key] 这样的方式访问, 当指定的key不存在时,是会抛出KeyError异常的。

但是,如果使用defaultdict,只要你传入一个默认的工厂方法,那么请求一个不存在的key时, 便会调用这个工厂方法使用其结果来作为这个key的默认值。

# -*- coding: utf-8 -*-
from collections import defaultdict

members = [
    # Age, name
    ["male", "John"],
    ["male", "Jack"],
    ["female", "Lily"],
    ["male", "Pony"],
    ["female", "Lucy"],
]

result = defaultdict(list)
for sex, name in members:
    result[sex].append(name)

print result

运行:

defaultdict(, {"male": ["John", "Jack", "Pony"], "female": ["Lily", "Lucy"]})

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41600.html

相关文章

  • 从❤️庄周梦蝶❤️寓言故事中感悟出一个科学真理:真假之间只相差一个 e^(iπ)

    昔者庄周梦为胡蝶,栩栩然胡蝶也。自喻适志与!不知周也。俄然觉,则蘧蘧然周也。不知周之梦为胡蝶与?胡蝶之梦为周与? ——典出《庄子·齐物论》 其故事大意为:庄周梦见自己变成一只蝴蝶,栩栩如生,感到十分愉快和惬意!不知道自己原本是庄周。突然间醒过来,惊惶不定之间方知原来自己是庄周。不知道是庄周梦中变成蝴蝶呢,还是蝴蝶梦见自己变成庄周呢? 庄周梦蝶是一则非常浪漫的寓言故事,它揭示了一个道理:这个纷繁...

    clasnake 评论0 收藏0
  • Python 弱引用 学习

    摘要:引用计数会记录给定对象的引用个数,并在引用个数为零时收集该对象。在对象群组内部使用弱引用即不会在引用计数中被计数的引用有时能避免出现引用环,因此弱引用可用于解决循环引用的问题。 参考 1.weakref – Garbage-collectable references to objects2.Python弱引用介绍 和许多其它的高级语言一样,Python使用了垃圾回收器来自动销毁那些不...

    philadelphia 评论0 收藏0
  • ❤️大佬都在学什么?Python爬虫分析C站大佬收藏夹,跟着大佬一起学, 你就是下一个大佬❤️!

    ❤️大佬都在学什么?Python爬虫分析C站大佬收藏夹,跟着大佬一起学,你就是下一个大佬❤️! 前言程序说明数据爬取获取 CSDN 作者总榜数据获取收藏夹列表获取收藏数据爬虫程序完整代码爬取数据结果 数据分析及可视化 前言 计算机行业的发展太快了,有时候几天不学习,就被时代所抛弃了,因此对于我们程序员而言,最重要的就是要时刻紧跟业界动态变化,学习新的技术,但是很多时候我们又不知道学什么好,万...

    Yang_River 评论0 收藏0
  • Python3 CookBook | 数据结构和算法(二)

    摘要:以下测试代码全部基于查找最大或最小的个元素工作中有时会遇到这样的需求,取出数据中前面的值,或者最后的值。大家如果对堆数据结构感兴趣的话,可以继续进行深入研究,由于我了解的并不深,也没办法再展开了。 文章首发于知乎专栏,欢迎关注。https://zhuanlan.zhihu.com/py... 以下测试代码全部基于 Python3 1、查找最大或最小的 N 个元素 工作中有时会遇到这样的...

    geekidentity 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<