感谢:

https://github.com/yidao620c/python3-cookbook

如有侵权,请联系我整改。

本文章节会严格按照原书(以便和原书对照,章节标题可能会略有修改),内容会有增删。

1.1 解引、解引赋值

1.1.1 解引

通过*可以解引(书中翻译为解压,还是解引更舒服些),

示例,

>>> (4,5)
(4, 5)
>>> print(*(4,5))
4 5
>>> str='akdfjasl'
>>> str
'akdfjasl'
>>> print(*str)
a k d f j a s l
>>> d={'a':1,'b':2}
>>> d
{'a': 1, 'b': 2}
>>> print(*d)
a b

1.1.2 解引赋值

可以用占位符,丢弃不要的数据。

示例,

>>> data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]
>>> _, shares, price, _ = data
>>> shares
50
>>> price
91.1
>>>

通过*可以赋值多个变量,

实例,

>>> *trailing, current = [10, 8, 7, 1, 9, 5, 10, 3]
>>> trailing
[10, 8, 7, 1, 9, 5, 10]
>>> current
3

1.3 只保留N个元素

from collections import deque

示例,

def search(lines, pattern, history=5):
previous_lines = deque(maxlen=history)
for line in lines:
if pattern in line:
yield line, previous_lines
previous_lines.append(line)

1.4 最大/最小的N个元素

import heapq

示例,

>>> portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
>>> cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
>>> cheap
[{'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}]

堆数据结构最重要的特征是 heap[0] 永远是最小的元素。并且剩余的元素可以很

容易的通过调用 heapq.heappop() 方法得到,该方法会先将第一个元素弹出来,然后

用下一个最小的元素来取代被弹出元素(这种操作时间复杂度仅仅是 O(log N))

示例,

>>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
>>> import heapq
>>> heap = list(nums)
>>> heapq.heapify(heap)
>>> heap
[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]
>>> heapq.heappop(heap)
-4
>>> heapq.heappop(heap)
1
>>> heapq.heappop(heap)
2

1.5 优先级队列

怎样实现一个按优先级排序的队列?并且在这个队列上面每次 pop 操作总是返回

优先级最高的那个元素

import heapq
class PriorityQueue:
def __init__(self):
self._queue = []
self._index = 0
def push(self, item, priority):
heapq.heappush(self._queue, (-priority, self._index, item))
self._index += 1
def pop(self):
return heapq.heappop(self._queue)[-1]

注意这个index,作用是当item本身不支持比较的时候,在priority相同时,可以通过index

比较,即,按照插入顺序排序

1.6 multidict(多值字典)

from collections import defaultdict

比如,

d = {
'a' : [1, 2, 3],
'b' : [4, 5]
}
e = {
'a' : {1, 2, 3},
'b' : {4, 5}
}

值可用list、set等存储

d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)
d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['b'].add(4)

defaultdict维护非常便利

1.7 OrderedDict(顺序字典)

from collections import OrderedDict

如果想控制字典顺序,可以用OrderedDict

[TODO]

1.8 字典运算

可以用zip打包成元组,

prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
min_price = min(zip(prices.values(), prices.keys()))
# min_price is (10.75, 'FB')

也可以用key

min(prices, key=lambda k: prices[k])

1.9 字典的异同

可以用keys()items()方法

a = {
'x' : 1,
'y' : 2,
'z' : 3
}
b = {
'w' : 10,
'x' : 11,
'y' : 2
}
# Find keys in common
a.keys() & b.keys() # { 'x', 'y' }
# Find keys in a that are not in b
a.keys() - b.keys() # { 'z' }
# Find (key,value) pairs in common
a.items() & b.items() # { ('y', 2) }
# Make a new dictionary with certain keys removed
c = {key:a[key] for key in a.keys() - {'z', 'w'}}
# c is {'x': 1, 'y': 2}

注意,字典的values()并不支持上述操作,原因是,值并不一定是相同的形式,

确切的讲,值中的元素个数可能是不同的;而键虽然形式也可能不同,但个数永远是1

1.10 删除相同元素,但保持原顺序

set结合yield

def dedupe(items, key=None):
seen = set()
for item in items:
val = item if key is None else key(item)
if val not in seen:
yield item
seen.add(val)

key方法的原因是,items并不一定是hashable的,比如dict

示例,

>>> a = [ {'x':1, 'y':2}, {'x':1, 'y':3}, {'x':1, 'y':2}, {'x':2, 'y':4}]
>>> list(dedupe(a, key=lambda d: (d['x'],d['y'])))
[{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
>>> list(dedupe(a, key=lambda d: d['x']))
[{'x': 1, 'y': 2}, {'x': 2, 'y': 4}]

注意,使用set()构造,或者使用set.add()都会改变顺序,后者还会排序

1.11 切片

>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[a] = [10,11]
>>> del items[a]

1.12 次数最多的元素

from collections import Counter

示例,

word_counts = Counter(words)
top_three = word_counts.most_common(3)
# Outputs [('eyes', 8), ('the', 5), ('look', 4)]

其中words可以是listtupple,当然set也可以,不过没有意义

Counter()返回的结果类似字典,形如,

Counter({'eyes':8,'the':5})

实际上,它的类型是<class 'collections.Counter'>

注意,虽然它看起来像字典,但某些操作和字典不同,比如,

update,在dict中,update意味着新值覆盖旧值,而在Counter中,

update意味着新增计数,在原有基础上增加

>>> d
{'a': 1, 'b': 2}
>>> d2
{'a': 1, 'b': 3}
>>> d.update(d2)
>>> d
{'a': 1, 'b': 3}
>>> w=dict(d)
>>> w
{'a': 1, 'b': 3}
>>> cw=Counter(w)
>>> cw
Counter({'b': 3, 'a': 1})
>>> w2=dict(w)
>>> cw.update(w2)
>>> cw
Counter({'b': 6, 'a': 2})

同时,Counterupdate,入参也可以是另一个Counter

除了updateCounter还支持+-运算

1.13 通过关键字给字典列表排序

from operator import itemgetter

示例,

rows_by_lfname = sorted(rows, key=itemgetter('lname','fname'))

itemgetter的效率比lambda高,结果是等价的

1.14 通过关键字给结构体列表排序

这里和1.13的区别是,上面是dict,这里是class

from operator import attrgetter

示例,

by_name = sorted(users, key=attrgetter('last_name', 'first_name'))

不限于sortedminmax都可以用,同itemgetter一样,效率比lamdba高,

至于,为何class不能用itemgetter,是因为key必须是一个callable对象,即,

()调用的,itemgetter一个class的属性,无法创建这样一个对象

1.15 通过某个字段分组

比如一堆记录,按日期进行分组。

from itertools import groupby

注意,groupby会按照顺序处理,所以在使用前,需要先进行排序

示例,

rows = [
{'address': '5412 N CLARK', 'date': '07/01/2012'},
{'address': '5148 N CLARK', 'date': '07/04/2012'},
{'address': '5800 E 58TH', 'date': '07/02/2012'},
{'address': '2122 N CLARK', 'date': '07/03/2012'},
{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
{'address': '1060 W ADDISON', 'date': '07/02/2012'},
{'address': '4801 N BROADWAY', 'date': '07/01/2012'},
{'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]
rows.sort(key=itemgetter('date'))
for date, items in groupby(rows, key=itemgetter('date')):
print(date)
for i in items:
print(' ', i) 07/01/2012
{'date': '07/01/2012', 'address': '5412 N CLARK'}
{'date': '07/01/2012', 'address': '4801 N BROADWAY'}
07/02/2012
{'date': '07/02/2012', 'address': '5800 E 58TH'}
{'date': '07/02/2012', 'address': '5645 N RAVENSWOOD'}
{'date': '07/02/2012', 'address': '1060 W ADDISON'}

groupby返回的是一个迭代器,内容类似一个tupple

1.16 列表推导

示例,

>>> mylist = [1, 4, -5, 10, -7, 2, 3, -1]
>>> import math
>>> [math.sqrt(n) for n in mylist if n > 0] //过滤,并计算
>>> clip_neg = [n if n > 0 else 0 for n in mylist] //值替代
>>> more5 = [n > 5 for n in counts] //返回true、false list

其中过滤,也可以用filter实现

true、false list可以结合from itertools import compresscompress来压缩表项

1.17 字典推导

prices = {
'ACME': 45.23,
'HPQ': 37.20,
'FB': 10.75
}
p1 = {key: value for key, value in prices.items() if value > 200}
tech_names = {'AAPL', 'IBM', 'HPQ', 'MSFT'}
p2 = {key: value for key, value in prices.items() if key in tech_names}

推导,比dict()构造效率高

1.18 命名元组

from collections import namedtuple

不再通过下标访问,而是通过类似字典的方式访问

虽然是tupple,但提供了_replace方法来修改元素内容

示例,

Stock = namedtuple('Stock', ['name', 'shares', 'price', 'date', 'time'])
stock_prototype = Stock('', 0, 0.0, None, None)
# Function to convert a dictionary to a Stock
def dict_to_stock(s):
return stock_prototype._replace(**s) >>> a = {'name': 'ACME', 'shares': 100, 'price': 123.45}
>>> dict_to_stock(a)
Stock(name='ACME', shares=100, price=123.45, date=None, time=None)

这里的字典解引很有意思,它等效于

stock_prototype._replace(name='acmd',shares=999)

1.19 聚集函数的推导

原文标题是,转换并同时计算数据。但看起来,形式类似推导。

聚集函数,summinmax等。

示例,

s = sum(x * x for x in nums)
min_shares = min(s['shares'] for s in portfolio)

minmax中,效果等效使用key

1.20 合并多个字典或映射

前文有讲过普通字典dict以及Counterupdate,

这里是另一种形式,

from collections import ChainMap

从名字上,它就是chain,链,将dict链起来,

当多个dict有键值重复时,返回首个值

《Python Cookbook v3.0.0》Chapter1 数据结构和算法的更多相关文章

  1. 《Python Cookbook v3.0.0》Chapter2 字符串、文本

    感谢: https://github.com/yidao620c/python3-cookbook 如有侵权,请联系我整改. 本文章节会严格按照原书(以便和原书对照,章节标题可能会略有修改),内容会有 ...

  2. 【python cookbook】【数据结构与算法】4.找到最大或最小的N个元素

    问题:想在某个集合中找出最大或最小的N个元素 解决方案:heapq模块中的nlargest()和nsmallest()两个函数正是我们需要的. >>> import heapq &g ...

  3. 【python cookbook】【数据结构与算法】18.将名称映射到序列的元素中

    问题:希望通过名称来访问元素,减少结构中对位置的依赖性 解决方案:使用命名元组collections.namedtuple().它是一个工厂方法,返回的是python中标准元组类型的子类,提供给它一个 ...

  4. 【python cookbook】【数据结构与算法】7.让字典保持有序

    问题:创建一个字典,同时对字典做迭代或序列化操作时,也能控制其中元素的顺序: 解决方案:可以使用collections模块中的OrderedDict类来控制字典中元素的顺序.当对字典做迭代时,他会严格 ...

  5. 【python cookbook】【数据结构与算法】5.实现优先级队列

    问题:要实现一个队列,它能够以给定的优先级对元素排序,且每次pop操作时都会返回优先级最高的那个元素: 解决方案:采用heapq模块实现一个简单的优先级队列 # example.py # # Exam ...

  6. 【推荐】.NETCore 简单且高级的库 csredis v3.0.0

    前言 .NETCore 从1.0发布历经坎坷,一开始各种库缺失到现在的部分完善,走到今天实属不易. 比如 redis-cli SDK 简直是坑出不穷. 过去 .net 最有名望的 ServiceSta ...

  7. Centos 6.8 安装 Protocol Buffers , v3.2.0有 BUG ,安装 3.1.0

    Centos 6.8 安装 Protocol Buffers   , v3.2.0有 BUG ,安装 3.1.0 切换到用户目录 cd ~ 安装 python2.7,须加入zlib wget http ...

  8. 《数据结构与算法之美》 <03>数组:为什么很多编程语言中数组都从0开始编号?

    提到数组,我想你肯定不陌生,甚至还会自信地说,它很简单啊. 是的,在每一种编程语言中,基本都会有数组这种数据类型.不过,它不仅仅是一种编程语言中的数据类型,还是一种最基础的数据结构.尽管数组看起来非常 ...

  9. FineUI(专业版)v3.2.0 发布(ASP.NET UI控件库)!

    +2016-08-20 v3.2.0 +表格增强. +表格列RenderField增加属性ClientHtmlEncode,用于在客户端进行HTML编码. -增加示例:单元格编辑->杂项-> ...

随机推荐

  1. Flex中利用事件机制进行主程序与子窗体间参数传递

    在开发具有子窗体,或者itemrenderer的应用时,常常涉及到子窗体向父窗体传递参数或者从itemrenderer内的控件向外部的主程序传递参数的需求.这些都可以通过事件机制这一统一方法加以解决. ...

  2. layui table 表格上添加日期控件

    方法一: var tableInit = table.render({ elem: '#tbtxrz' , method: 'post' , data: jsonData , height: &quo ...

  3. API安全综述

    API安全综述 译自:An Overview on API Security. 本文概括了API防护有关的方方面面,从上层视角介绍了API防护中主要注意的点,并给出了相应的建议.本文可以作为一个API ...

  4. jdk keytool 自签证书

    jdk keytool 自签证书 https需要用到ssl证书,可以从阿里等平台申请,本文采用jdk keytool进行自签证书. 生成环境:linux 用jdk自带keytool工具生成密钥库 ke ...

  5. bcprov-jdk15-145.rar

    javapdf文件操作,加密包 bcprov-jdk15-145.rar https://files.cnblogs.com/files/blogs/692137/bcprov-jdk15-145.r ...

  6. mysql 的基础操作

    1.建表 create table  表名( 字段一 数据类型 [列属性] , 字段二 数据类型 [列属性], ......... )[表类型][表字符集][注释]; 注意:MySQL命令终止符为分号 ...

  7. IDA 动态调试

    感谢南邮,让我把ida动态调试,给搞定了,困扰了很久,之前下的ubuntu的源,好像有问题,ifconfig这个命令一直装不上,突然想起来了我的服务器很久没用了,重装了下系统,换成ubuntu,这里记 ...

  8. WPF教程十:如何使用Style和Behavior在WPF中规范视觉样式

    在使用WPF编写客户端代码时,我们会在VM下解耦业务逻辑,而剩下与功能无关的内容比如动画.视觉效果,布局切换等等在数量和复杂性上都超过了业务代码.而如何更好的简化这些编码,WPF设计人员使用了Styl ...

  9. SpringBoot | 2.1 SpringBoot自动装配原理

    @ 目录 前言 1. 引入配置文件与配置绑定 @ImportResource @ConfigurationProperties 1.1 @ConfigurationProperties + @Enab ...

  10. Java的代理模式

    最近在学习Spring,关于Spring AOP的代理模式不是很了解,看了一篇博文就懂了. https://www.cnblogs.com/cenyu/p/6289209.html Java的三种代理 ...