第一章 数据结构和算法

1.1 将序列分解为单独的变量

适用于元组、列表、字符串等。只要是可迭代的对象,都可以执行分解操作。唯一的要求是变量的总数和结构要与序列相同。

1.2 从任意长度的可迭代对象中分解元素

“*表达式”

以下代码中使用的“*args”,如果去掉*,是会报错的。

records = [('foo',1,2),('bar','hello'),('foo',3,4)]
for tag,*args in records:
print(tag,*args)

拆分操作,和split结合使用,会实现非常好用的功能:

line = 'nobody:*:-2:-2:Unprivileged User:/Var/empty:/usr/bin/false'
uname,*fields,homedir,sh = line.split(':')

1.3 保留最后N个元素

下边一段代码还不是特别理解,对生成器比较生疏。

from collections import deque

def search(lines,pattern,history):
previous_lines = deque(maxlen=history)
for line in lines:
if pattern in line:
yield line,previous_lines
previous_lines.append(line) if __name__ == '__main__':
with open('somefile.txt') as f:
for line,prevlines in search(f,'Python',5):
for pline in prevlines:
print(pline,end='')
print(line,end='')
print('-'*20)

deque(maxlen=N)创建一个固定长度的队列,有新元素添加时,会自动删除最老的记录。

不指定长度的时候,创建一个无界限的队列:

from collections import deque
q = deque()
q.append(1)
q.append(2)
q.append(3)
print(q) q.append(4)#右边添加元素
q.appendleft(0)#左边添加元素
print(q)
q.pop()#删除最右边元素
print(q)
q.popleft()#删除左边元素
print(q)

1.4 找到最大或最小的N个元素

heapq模块中的nlargest和nsmallest函数:

import heapq
nums = [1,8,2,23,7,-4,16,23,42,37,2]
print(heapq.nlargest(3,nums))
print(heapq.nsmallest(3,nums))

提供一个参数key,使其工作在更复杂的结构上:

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'])
print(cheap)
expensive = heapq.nlargest(3,portfolio,key=lambda s: s['price'])
print(expensive)

如果正在寻找最大或者最小的N个元素,且同集合中元素的总数目相比,N很小,那么可以使用以下函数(性能更好):为什么?

nums = [1,8,2,23,7,-4,16,23,42,37,2]
heap = list(nums) #找到第3小的元素
heapq.heappop(heap)
heapq.heappop(heap)
heapq.heappop(heap)

当所要寻找的元素数量相对较小时,nlargest和nsmallest函数才是最适用的。如果只是简单寻找最大和最小值,那么max和min函数会更快。如果N和集合本身大小差不多,通常更快的方法是先对集合排序,然后进行切片操作( sorted(items)[:N] 和sorted(items)[-N:] )。

1.5 实现优先级队列(暂时搁置)

1.6 在字典中将键映射到多个值上

一键多值字典,可以使用collections模块中的defaultdict类:

from collections import defaultdict

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

使用列表还是集合,取决于实际需要,注重顺序,则使用列表;希望去除重复值,则使用集合。

以上方法会自动创建字典表项(什么东西)以待稍后访问,也可以在普通字典上使用setdefault方法:

d = {}
d.setdefault('a',[]).append(1)
d.setdefault('a',[]).append(2)
d.setdefault('b',[]).append(3)
print(d)

1.7 让字典保持有序

collections模块中的OrderedDict类可使字典在迭代的时候保持严格按照元素初始添加的时候的顺序:

from collections import OrderedDict
d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4 for key in d:
print(key,d[key])

因为对字典的特性了解的还不够深,所以对这种好处的理解不是很深刻。

json编码时严格控制字段的顺序,就可以使用此种方法:

import json
json.dumps(d)

OrderedDict内部维护了一个双向链表,根据元素添加的顺序来排列键的位置,大小是普通字典的两倍多,在使用的时候就要衡量其带来的好处和增加的额外内存开销的缺点。

 1.8 与字典有关的计算问题

zip()会将字典的键和值反转过来,然后进行一些计算,比如求最值、排序等:

prices = {'ACME':45.23,
'AAPL':612.78,
'IBM':205.55,
'HPQ':27.20,
'FB':10.75}
min_prices = min(zip(prices.values(),prices.keys()))
max_prices = max(zip(prices.values(),prices.keys()))
sorted_prices = sorted(zip(prices.values(),prices.keys()))

zip创建一个迭代器(?),内容只能被消费一次,以下代码会报错:

prices_and_names = zip(prices.values(),prices.keys())
print(min(prices_and_names))
print(max(prices_and_names))

在字典上执行常规的数据操作(例如min(prices)),结果是只处理键,而不处理值;如果想利用字典的values()方法解决这个问题,结果只看到值得结果看不到对应的键的信息。

zip将字典的键值对反转为值键对,在这样的元组上进行比较时,值会先进行比较,然后再比较键。如果有多个键对应着相同的值,这时候key就将称为判定结果的依据。

1.9 在两个字典中寻找相同点

通过keys()或者items()执行集合操作即可实现:

a = {'x':1,'y':2,'z':3}
b = {'w':10,'x':11,'y':2}
a.keys() & b.keys()
a.keys() - b.keys()
a.items() & b.items() c = {key:a[key] for key in a.keys() - {'z','w'}}

注意,对于集合的values()方法不支持集合操作。可以将值转化为集合后来操作。

1.10 从序列中移除重复项且保持元素间顺序不变

1.11 对切片命名

从字符串的固定位置取出具体的数据:

record = '....................100.......513.25..........'
cost = int(record[20:23]) * float(record[30:36])

避免使用许多神秘难懂的硬编码索引,使用切片命名:

shares = slice(20,23)
prices = slice(30,36)
cost = int(record[shares]) * float(record[prices])

slice对象实例s可以通过s.start, s.stop, s.step属性获取实例对象的信息:

a = slice(2,40,5)
a.start
a.stop
a.step

可以通过使用indices(size)方法将切片映射到特定大小的序列上,会返回一个(start, stop, step)元组。

s = 'HelloWorld'
a.indices(len(s))
for i in range(*a.indices(len(s))):
print(s[i])

range参数里的*号是做什么的呢?

1.12 找出序列中出现次数最多的元素

collections模块中的Counter类:

words = ["twinkle", "twinkle", "little", "star",
"how", "i", "wonder", "what", "you", "are",
"up", "above", "the", "world", "so", "high",
"like", "a", "diamond", "in", "the", "sky",
"twinkle", "twinkle", "little", "star",
"how", "i", "wonder", "what", "you", "are"] from collections import Counter
wordsCounts = Counter(words)
top_three = wordsCounts.most_common(3)

在底层实现中,Counter是一个字典,在元素和出现次数之间做了映射,我们可以通过以下方式查看某个单词出现的次数:

print(wordsCounts["i"])

使用update方法增加计数:

morewords = ["like", "a", "diamond", "in", "the", "sky"]
wordsCounts.update(morewords)
print(wordsCounts)

Counter对象可以同各种数学运算操作结合起来:

a = Counter(words)
b = Counter(morewords)
c = a+b
print(c)
d = a-b
print(d)

1.13 通过公共键对字典列表排序

根据一个或者多个字典中的值对列表排序,利用operator模块中的itemgetter函数:

rows = [{"fname":"Brain" , "lname": "Jones", "uid": 1003},
{"fname":"David" , "lname": "Beazley", "uid": 1002},
{"fname":"John" , "lname": "Cleese", "uid": 1001},
{"fname":"Big" , "lname": "Jones", "uid": 1004}] from operator import itemgetter
rows_by_fname = sorted(rows, key=itemgetter('fname'))
print(rows_by_fname) rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_uid)

itemgetter函数可以接受多个参数:

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

有时候用lambda表达式取代itemgetter()的功能:

rows_by_fname = sorted(rows, key=lambda r: r['fname'])
print(rows_by_fname)

除了可以使用sorted()函数之外,还可以用与min()与max()函数。

1.14 对不原生支持比较操作的对象排序

PythonCookbook读书笔记的更多相关文章

  1. python-cookbook读书笔记

    今天开始读<python-cookbook>,书里有许多python优雅的写法,可以作为python的一本进阶书. 感谢译者.项目地址: https://github.com/yidao6 ...

  2. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  3. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  4. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  5. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  6. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  7. Web高级征程:《大型网站技术架构》读书笔记系列

    一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...

  8. LOMA280保险原理读书笔记

    LOMA是国际金融保险管理学院(Life Office Management Association)的英文简称.国际金融保险管理学院是一个保险和金融服务机构的国际组织,它的创建目的是为了促进信息交流 ...

  9. 《3D Math Primer for Graphics and Game Development》读书笔记2

    <3D Math Primer for Graphics and Game Development>读书笔记2 上一篇得到了"矩阵等价于变换后的基向量"这一结论. 本篇 ...

随机推荐

  1. linux各种终端类型的区别和概念

    1 pty(虚拟终端或伪终端): 当我们远程telnet到主机或使用xterm时不也需要一个终端交互么?是的,这就是虚拟终端pty(pseudo-tty). 2 tty(终端设备的统称):tty一词源 ...

  2. Gitlab仓库搭建及在Linux/windows中的免密使用

    1. Gitlab简介 Gitlab:代码私有仓库,可以使用Git进行代码的管理. GitHub:公共仓库. GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭 ...

  3. MariaDB数据库(三)

    1. 基本查询 查询基本使用包括:条件.排序.聚合函数.分组和分页. 实例详解查询 1> 创建students表用作实验 MariaDB [testdb]> drop table stud ...

  4. python 基础知识汇总—— if else while continue

    1.if 语句 什么是if语句?if语句用来干什么的? if语句说通俗点,就是判断,如果判断条件为真,那么就执行语句,就像我们生活中例子,如果你饿了,判断为真,就要吃饭,于是你就会执行吃饭这个动作,如 ...

  5. Python的第二堂课(1)

    一.编程语言的分类 机器语言:直接使用二进制命令去编写程序. 优点:执行效率高 缺点:开发效率低 汇编语言:用英文标签代替二进制命令去编写程序 优点:开发效率高于机器语言 缺点:执行效率低于机器语言 ...

  6. Cocos2d-x学习资料集锦

    Cocos2d-x学习资料集锦: 1.Cocos2d-x官方中文文档:https://github.com/chukong/cocos-docs/blob/master/catalog/zh.md 推 ...

  7. Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控

    2.可写的计算监控 初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的. 通常,计算监控是一个通过其他监控值计算出的值,因此是只读的. 令人惊讶的是,可以使计算监控值 ...

  8. swift final关键字、?、!可选与非可选符

    ?符号: 可选型 在初始化时可以赋值为nil !符号:  隐形可选型 类型值不能为nil,如果解包后的可选类型为nil会报运行时错误,主要用在一个变量/常量在定义瞬间完成之后值一定会存在的情况.这主要 ...

  9. liunx 根目录介绍

    1. /bin binary二进制 存放系统许多可执行程序文件 执行的相关指令,例如ls pwd whoami,后台的支持文件目录 2. /sbin super binary超级的二进制 存放系统许多 ...

  10. HDu-1247 Hat’s Words,字典树裸模板!

    Hat's Words 题意:给出一张单词表求有多少个单词是由单词表里的两个单词组成,可以重复!按字典序输出这些单词. 思路:先建一个字典树,然后枚举每个单词,把每个单词任意拆分两部分然后查找. 目测 ...