http://blog.csdn.net/pipisorry/article/details/46947833

python额外的数据类型。collections模块和heapq模块的主要内容。

集合库collection

collections模块介绍

Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型:
1.namedtuple(): 生成可以使用名字来访问元素内容的tuple子类
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典

Named tuples元素命名的元组(collections.namedtuple)

>>> Point = collections.namedtuple('Point', ['x', 'y'])
>>> p = Point(x=1.0, y=2.0)
>>> p
Point(x=1.0, y=2.0)
>>> p.x
1.0
>>> p.y
2.0

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

举个例子

比如我们用户拥有一个这样的数据结构,每一个对象是拥有三个元素的tuple。使用namedtuple方法就可以方便的通过tuple来生成可读性更高也更好用的数据结构。
"""
from collections import namedtuple
websites = [
('Sohu', 'http://www.google.com/', u'张朝阳'),
('Sina', 'http://www.sina.com.cn/', u'王志东'),
('163', 'http://www.jbxue.com/', u'丁磊')
]
Website = namedtuple('Website', ['name', 'url', 'founder'])
for website in websites:
website = Website._make(website)
print website
# Result:
Website(name='Sohu', url='http://www.google.com/', founder=u'\u5f20\u671d\u9633')
Website(name='Sina', url='http://www.sina.com.cn/', founder=u'\u738b\u5fd7\u4e1c')

Website(name='163', url='http://www.jbxue.com/', founder=u'\u4e01\u78ca')

继承命名tuples

>>> class Point(collections.namedtuple("PointBase", ["x", "y"])):

... __slots__ = ()

... def __add__(self, other):

... return Point(x=self.x + other.x, y=self.y + other.y)

...

>>> p = Point(x=4.0, y=2.0)

>>> q = Point(x=2.0, y=3.0)

>>> p + q

Point(x=6.0, y=5.0)

deque双端队列

deque其实是 double-ended queue 的缩写,翻译过来就是双端队列,它最大的好处就是实现了从队列 头部快速增加和取出对象: .popleft(), .appendleft() 。
你可能会说,原生的list也可以从头部添加和取出对象啊?就像这样:
l.insert(0, v)
l.pop(0)

list对象的这两种用法的时间复杂度是 O(n) ,也就是说随着元素数量的增加耗时呈 线性上升。而使用deque对象则是 O(1) 的复杂度,所以当你的代码有这样的需求的时候, 一定要记得使用deque。
作为一个双端队列,deque还提供了一些其他的好用方法,比如 rotate 等。
举个栗子
使用deque的rotate方法来实现了一个无限循环的加载动画
import sys
import time
from collections import deque
fancy_loading = deque('>--------------------')
while True:
print '\r%s' % ''.join(fancy_loading),
fancy_loading.rotate(1)
sys.stdout.flush()
time.sleep(0.08)
# Result:
# 一个无尽循环的跑马灯
------------->-------

双向队列操作

>>> Q =collections.deque()

>>> Q.append(1)

>>> Q.appendleft(2)

>>> Q.extend([3,4])

>>> Q.extendleft([5,6])

>>> Q

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

>>> Q.pop()

4

>>> Q.popleft()

6

>>> Q

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

>>> Q.rotate(3)

>>> Q

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

>>> Q.rotate(-3)

>>> Q

deque([5,2,1,3])
限制长度的双向队列

>>> last_three = collections.deque(maxlen=3)

>>> foriinxrange(10):

... last_three.append(i)

... print", ".join(str(x)forxinlast_three)

...

0

0,1

0,1,2

1,2,3

2,3,4

皮皮Blog

Counter计数器 - Multisets运算

A Counter is a dict subclass for counting hashable objects.It is an unordered collection where elements are stored as dictionary keysand their counts are stored as dictionary values. Counts are allowed to beany integer value including zero or negative counts. The Counter class is similar to bags or multisets in other languages.

统计所有字符出现次数
from collections import Counter
counter = Counter()
a = '隐蔽式喷淋头盖板面板装饰板 外壳 whats app'
counter.update(a)
print(counter)

Counter({'板': 3, ' ': 3, 'a': 2, 'p': 2, '隐': 1, '蔽': 1, '式': 1, '喷': 1, '淋': 1, '头': 1, '盖': 1, '面': 1, '装': 1, '饰': 1, '外': 1, '壳': 1, 'w': 1, 'h': 1, 't': 1, 's': 1})

统计字符串出现次数

counter.update([a])

Counter方法

counter还有几个自己独有的方法如下:

elements()

Return an iterator over elements repeating each as many times as itscount. Elements are returned in arbitrary order. If an element’s countis 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]) 获取出现频率最高的n个/按频率降序的字符

Return a list of the n most common elements and their counts from themost common to the least. If n is omitted or None,most_common() returns all elements in the counter.Elements with equal counts are ordered arbitrarily:

>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]

subtract([iterable-or-mapping])

Elements are subtracted from an iterable or from another mapping(or counter). Like dict.update() but subtracts counts insteadof 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})

除了fromkeys和update外,counter支持所有dict的其它函数。如返回所有的值counter.values()。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 anothermapping (or counter). Like dict.update() but adds countsinstead of replacing them. Also, the iterable is expected to be asequence of elements, not a sequence of (key, value) pairs.

counter = Counter()
for c in c_type_list:counter.update(c)

Another, maybe better, example might be counting all the different lines that appear in a file. It becomes very simple

with open('/some/file', 'r') as f:line_count = Counter(f)

Multisets运算

>>> A =collections.Counter([1,2,2])

>>> B =collections.Counter([2,2,3])

>>> A

Counter({2:2,1:1})

>>> B

Counter({2:2,3:1})

>>> A | B

Counter({2:2,1:1,3:1})

>>> A & B

Counter({2:2})

>>> A +B

Counter({2:4,1:1,3:1})

>>> A -B

Counter({1:1})

>>> B -A

Counter({3:1})
[Counter objects]

OrderedDict有序字典

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

>>> m = dict((str(x), x) for x in range(10))
>>> print ', '.join(m.keys())
1, 0, 3, 2, 5, 4, 7, 6, 9, 8
>>> m = collections.OrderedDict((str(x), x) for x in range(10))
>>> print ', '.join(m.keys())
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
>>> m = collections.OrderedDict((str(x), x) for x in range(10, 0, -1))
>>> print ', '.join(m.keys())
10, 9, 8, 7, 6, 5, 4, 3, 2, 1

举个栗子
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
# Result:
Regular Dict:
A 1
C 3
B 2
Ordered Dict:
A 1
B 2
C 3

Note:直接输出的OrderedDict形式如下:print(OrderedDict(reguale_slist))

OrderedDict([('GET', 'http://www.jobbole.com/login/?redirect=http://www.jobbole.com/ HTTP/1.1'), ('Host', 'www.jobbole.com'), ('Connection', 'keep-alive'),  ('Cookie', 'wordpress_test_cookie=WP+Cookie+check')...])

而不是dict的形式:print(dict(reguale_slist))

{'Referer': 'http://www.jobbole.com/', 'Host': 'www.jobbole.com', 'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate, sdch', ...}

defaultdict默认字典

我们都知道,在使用Python原生的数据结构dict的时候,如果用 d[key] 这样的方式访问, 当指定的key不存在时,是会抛出KeyError异常的。
但是,如果使用defaultdict,只要你传入一个默认的工厂方法,那么请求一个不存在的key时, 便会调用这个工厂方法使用其结果来作为这个key的默认值。

defaultdict字典元素类型初始化

collections.defaultdict([default_factory[,...]])

default_factory指定字典的value类型

from collections import defaultdict
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)...
>>> d.items()

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

如果给default_dict传入int,则可以用来计数:
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
>>> d.items()

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

Note:defaultdict()参数设置成int,那么就设置字典值的初始值为0了

嵌套defaultdict

from collections import defaultdict
u_lt_ts_dict = defaultdict(lambda: defaultdict(list))

但是这个对象是不可序列化的,因为有lamba函数。也可以这样

from collections import defaultdict
from functools import partial
u_lt_ts_dict = defaultdict(partial(defaultdict, list))

这样就可以pickle了。

[Multiple levels of 'collection.defaultdict' in Python]

Using default dictionaries to represent simple trees

>>> import json
>>> tree = lambda: collections.defaultdict(tree)
>>> root = tree()
>>> root['menu']['id'] = 'file'
>>> root['menu']['value'] = 'File'
>>> root['menu']['menuitems']['new']['value'] = 'New'
>>> root['menu']['menuitems']['new']['onclick'] = 'new();'
>>> root['menu']['menuitems']['open']['value'] = 'Open'
>>> root['menu']['menuitems']['open']['onclick'] = 'open();'
>>> root['menu']['menuitems']['close']['value'] = 'Close'
>>> root['menu']['menuitems']['close']['onclick'] = 'close();'
>>> print json.dumps(root, sort_keys=True, indent=4, separators=(',', ': '))
{"menu": {"id": "file","menuitems": {"close": {"onclick": "close();","value": "Close"},"new": {"onclick": "new();","value": "New"},"open": {"onclick": "open();","value": "Open"}},"value": "File"}
}

(See https://gist.github.com/hrldcpr/2012250 for more on this.)

[一行Python代码实现树结构]

Mapping objects to unique counting numbers (collections.defaultdict)

>>> import itertools, collections
>>> value_to_numeric_map = collections.defaultdict(itertools.count().next)
>>> value_to_numeric_map['a']
0
>>> value_to_numeric_map['b']
1
>>> value_to_numeric_map['c']
2
>>> value_to_numeric_map['a']
0

举个栗子
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
# Result:
defaultdict(<type 'list'>, {'male': ['John', 'Jack', 'Pony'], 'female': ['Lily', 'Lucy']})

[Python collections模块实例]

常用操作

>>> m =dict()

>>> m["a"]

Traceback (most recent call last):

File"<stdin>", line1,in<module>

KeyError: "a"

>>>

>>> m =collections.defaultdict(int)

>>> m["a"]

0

>>> m["b"]

0

>>> m =collections.defaultdict(str)

>>> m["a"]

""

>>> m["b"]+="a"

>>> m["b"]

"a"

>>> m =collections.defaultdict(lambda:"[default value]")

>>> m["a"]

"[default value]"

>>> m["b"]

"[default value]"
使用defaultdict代表tree

>>> importjson

>>> tree = lambda: collections.defaultdict(tree)

>>> root = tree()

>>> root["menu"]["id"]="file"

>>> root["menu"]["value"]="File"

>>> root["menu"]["menuitems"]["new"]["value"]="New"

>>> root["menu"]["menuitems"]["new"]["onclick"]="new();"

>>> root["menu"]["menuitems"]["open"]["value"]="Open"

>>> root["menu"]["menuitems"]["open"]["onclick"]="open();"

>>> root["menu"]["menuitems"]["close"]["value"]="Close"

>>> root["menu"]["menuitems"]["close"]["onclick"]="close();"

>>> printjson.dumps(root, sort_keys=True, indent=4, separators=(",",": "))

{

"menu": {

"id":"file",

"menuitems": {

"close": {

"onclick":"close();",

"value":"Close"

},

"new": {

"onclick":"new();",

"value":"New"

},

"open": {

"onclick":"open();",

"value":"Open"

}

},

"value":"File"

}

}

[查看更多]
映射对象到唯一的计数数字

>>> importitertools, collections

>>> value_to_numeric_map=collections.defaultdict(itertools.count().next)

>>> value_to_numeric_map["a"]

0

>>> value_to_numeric_map["b"]

1

>>> value_to_numeric_map["c"]

2

>>> value_to_numeric_map["a"]

0

>>> value_to_numeric_map["b"]

1
皮皮blog

堆队列heapq — Heap queue algorithm

这个模块提供了堆队列算法的实现,也称为优先队列算法。

默认是个最小堆。堆是一个二叉树,它的每个父节点的值都只会小于或等于所有孩子节点(的值)。 它使用了数组来实现:从零开始计数,对于所有的 k ,都有 heap[k] <= heap[2*k+1]heap[k] <= heap[2*k+2]。 为了便于比较,不存在的元素被认为是无限大。 堆最有趣的特性在于最小的元素总是在根结点:heap[0]

这个API与教材的堆算法实现有所不同,具体区别有两方面:(a)我们使用了从零开始的索引。这使得节点和其孩子节点索引之间的关系不太直观但更加适合,因为 Python 使用从零开始的索引。 (b)我们的 pop 方法返回最小的项而不是最大的项(这在教材中称为“最小堆”;而“最大堆”在教材中更为常见,因为它更适用于原地排序)。

基于这两方面,把堆看作原生的Python list也没什么奇怪的: heap[0] 表示最小的元素,同时 heap.sort() 维护了堆的不变性!

heap = []

heapq.heappush(heap, item)

将 item 的值加入 heap 中,保持堆的不变性。Push the value item onto the heap, maintaining the heap invariant.

Note: item可以是tuple类型带卫星数据,默认使用item[0]进行排序,如

heapq.heapify(x

将list x 转换成堆,原地,线性时间内。

heapq.heappop(heap)

弹出并返回 heap 的最小的元素,保持堆的不变性。如果堆为空,抛出 IndexError 。使用 heap[0] ,可以只访问最小的元素而不弹出它。Pop and return the smallest item from the heap, maintaining the heapinvariant. If the heap is empty, IndexError is raised. To access thesmallest item without popping it, use heap[0].

heapq.heappushpop(heap, item)

Push item on the heap, then pop and return the smallest item from the heap. The combined action runs more efficiently than heappush()followed by a separate call to heappop().
heapq.heapreplace(heap, item)

弹出并返回 heap 中最小的一项,同时推入新的 item。 堆的大小不变。 如果堆为空则引发 IndexError。

这个单步骤操作比 heappop() 加 heappush() 更高效,并且在使用固定大小的堆时更为适宜。 pop/push 组合总是会从堆中返回一个元素并将其替换为 item。

返回的值可能会比添加的 item 更大。 如果不希望如此,可考虑改用 heappushpop()。 它的 push/pop 组合会返回两个值中较小的一个,将较大的值留在堆中。

heapq.merge(*iterables, key=None, reverse=False)

将多个已排序的输入合并为一个已排序的输出(例如,合并来自多个日志文件的带时间戳的条目)。 返回已排序值的 iterator。

heapq.nlargest(n, iterable, key=None)

Return a list with the n largest elements from the dataset defined byiterable. key, if provided, specifies a function of one argument that isused to extract a comparison key from each element in the iterable:key=str.lower Equivalent to: sorted(iterable, key=key,reverse=True)[:n]

heapq.nsmallest(n, iterable, key=None)

Return a list with the n smallest elements from the dataset defined byiterable. key, if provided, specifies a function of one argument that isused to extract a comparison key from each element in the iterable:key=str.lower Equivalent to: sorted(iterable, key=key)[:n]

[heapq --- 堆队列算法¶]**

示例

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')

维护top n的最小堆(最大的k个元素)

def push(self, x):"""Pushes a new element."""assert self._data is not Noneif len(self._data) < self._n:heapq.heappush(self._data, x)else:heapq.heappushpop(self._data, x)

第k大的元素

import heapq
class Solution:def findKthLargest(self, nums: List[int], k: int) -> int:maxk_l = []for i in range(k):heapq.heappush(maxk_l, nums[i])for i in nums[k:]:min0 = maxk_l[0]if min0 < i:heapq.heappushpop(maxk_l, i)return maxk_l[0]

return maxk_l即最大的k个元素。

[https://leetcode-cn.com/problems/kth-largest-element-in-an-array/submissions/]

解法2:

from typing import List
import heapqclass Solution:# 使用容量为 k 的小顶堆# 元素个数小于 k 的时候,放进去就是了# 元素个数大于 k 的时候,小于等于堆顶元素,就扔掉,大于堆顶元素,就替换def findKthLargest(self, nums: List[int], k: int) -> int:size = len(nums)if k > size:raise Exception('程序出错')L = []for index in range(k):# heapq 默认就是小顶堆heapq.heappush(L, nums[index])for index in range(k, size):top = L[0]if nums[index] > top:# 看一看堆顶的元素,只要比堆顶元素大,就替换堆顶元素heapq.heapreplace(L, nums[index])# 最后堆顶中的元素就是堆中最小的,整个数组中的第 k 大元素return L[0]

[https://leetcode-cn.com/problems/kth-largest-element-in-an-array/solution/partitionfen-er-zhi-zhi-you-xian-dui-lie-java-dai-/]

最大 & 最小的k个元素(heapq.nlargest and heapq.nsmallest)

>>> a =[random.randint(0,100)for__inxrange(100)]

>>> heapq.nsmallest(5, a)

[3,3,5,6,8]

>>> heapq.nlargest(5, a)

[100,100,99,98,98]
[其具体实现算法可以参考:编程之美之2.5 寻找最大的K个数 ]
[A fast way to find the largest N elements in an numpy array]
[How to get indices of N maximum values in a numpy array?]
[heapq — Heap queue algorithm]

from:http://blog.csdn.net/pipisorry/article/details/46947833

ref: [collections — Container datatypes]

[Data Types]

python标准库:collections和heapq模块相关推荐

  1. 细数python标准库中低调的模块

    有没有遇到过这种情况,在网络上搜索如何使用Python进行某种操作,最终找到一个第三方库,直到后来发现标准库中包含的模块或多或少都可以满足你的需求.这种情况并不罕见, 整理了一些python标准库中鲜 ...

  2. Python标准库datetime之date模块详解

    Python标准库datetime之date模块详解 datetime是Python提供的操作日期和时间的标准库,主要有datetime.date模块.datetime.time模块及datetime ...

  3. Python标准库笔记(9) — functools模块

    functools 作用于函数的函数 functools 模块提供用于调整或扩展函数和其他可调用对象的工具,而无需完全重写它们. 装饰器 partial 类是 functools 模块提供的主要工具, ...

  4. Python标准库datetime之datetime模块详解

    Python标准库datetime之datetime模块详解 1.日期时间对象 日期时间对象是指具有日期(年月日)和时间(时分秒)双重属性的实例 日期时间对象的类型为datetime.datetime ...

  5. Python标准库collections中与字典有关的类

    Python标准库中提供了很多扩展功能,大幅度提高了开发效率.这里主要介绍OrderedDict类.defaultdict类和Counter类. (1)OrderedDict类 Python内置字典d ...

  6. Python标准库中的os模块

     Python的标准库中的os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的.即它允许一个程序在编写后不需要任何改动,也不会发生任何问题,就可以在Linux ...

  7. Python标准库collections库:超好用的counter计数器,不接受反驳!

    collections是python的标准库,它提供了一些解决特定问题的容器,也就是说有些问题虽然可以用list,tuple,dict解决,但解决起来太麻烦,而这些问题又经常遇到,所以他们就把这些问题 ...

  8. Python标准库中的pickle模块

     pickle  -  Python对象序列化. pickle模块实现了用于序列化和反序列化Python对象结构的二进制协议."pickle"是将Python对象层次结构转换为 ...

  9. Python标准库中的marshal模块

     marshal-内部的Python对象序列化 该模块包含可以以二进制格式读取和写入Python值的函数.该格式是针对Python的,但独立于机器架构问题(例如,您可以将Python值写入PC上的 ...

  10. Python标准库——collections模块的Counter类

    更多16 最近在看一本名叫<Python Algorithm: Mastering Basic Algorithms in the Python Language>的书,刚好看到提到这个C ...

最新文章

  1. 01_Mybatis入门
  2. helloworld:一个完整的WCF案例
  3. C#LeetCode刷题之#448-找到所有数组中消失的数字(Find All Numbers Disappeared in an Array)
  4. jsch上传下载文件名称中文乱码
  5. SpringBoot的@Conditional和自动配置类生效
  6. java 内存指针_C指针和内存
  7. Leetcode每日一题:125.valid-palindrome(验证回文串)
  8. java操作oracle数据库 代码案例
  9. qmake构建项目详细讲解
  10. python基础之centos7源码安装python3
  11. 自动驾驶_基于强化学习的自动驾驶系统
  12. xfs文件系统修复-xfs_repair
  13. oblog46_Final_20080623 软件下载
  14. Jcrop+ajaxFileUpload 图片裁切上传 oss(java web)
  15. 计算机型号win7,教你win7系统电脑内存条型号怎么看
  16. idea 编译通过,无法调试 Frames are not available
  17. java手机振动软件_Android实现手机震动效果
  18. [pytorch]yolov3.cfg参数详解(每层输出及route、yolo、shortcut层详解)
  19. 什么是大数据的ETL
  20. Spring Boot使用spring-data-jpa配置Mysql多数据源

热门文章

  1. 20144303 《Java程序设计》第一周学习总结
  2. MS Sql当中 money类型数据使用 Decimal 传输
  3. magento Service Temporarily Unavailable
  4. 10个免费的PHP编辑器/开发工具
  5. 2019windows上安装Mac OS 10.14过程详细截图
  6. vs code 的便捷使用
  7. 【1】ArcGIS API for JavaScript 4.5/4.6 本地部署
  8. 简述redux(1)
  9. js二(多)叉树算法
  10. Akari谜题(关灯问题)的开灯解法