python进阶-内部数据结构和算法

本文内容整理自《Python Cookbook》,仅用作本人学习笔记,若侵犯原著权益请尽快联系本人。


1.将序列分解为单独变量

  • 理解多重赋值
  • 丢弃元素方法
data = ('Kevin', 50, 100, (2017, 2, 28))
name, shares, _, date = data

# _ 变量理解为忽略该位置元素

2.从任意长度的可迭代对象中分离元素

  • 理解*args为取序列
record = ('Kevin', 50, 100, (2017, 2, 28))
name, *_,(*_,year) = record

# *args会贪婪的获取元祖成员

3.保存最后N个元素

  • 掌握collections.deque用法
  • deque从两端增删元素复杂度为O(1),普通列表从头部删除元素复杂度为O(N)
from collections import deque
q = deque(maxlen=5)
q.append((1,2))
q.append(4)
q.appendleft(3)
print(q)
q.pop()
q.popleft()
print(q)
##print
# deque([3, (1, 2), 4], maxlen=5)
# deque([(1, 2)], maxlen=5)

4.找到最大或最小的N个元素

  • 熟悉堆模块heapq
  • heapq.nlargest(n, list, key)
  • heapq.nsmallest(n, list, key) #key为可自定义函数
  • heapq.heapify(list) #堆化,当list数目较小时比上面快
  • max(),min()在取单个元素时较快
  • 若待取元素数量接近于列表大小,则先排序再切片性能最好(nlargest和nsmallest也会自动判断这个问题)

5.实现优先级队列

  • heapq.heappush(list,item)
  • heapq.heappop(list)
  • 注意默认生成的堆是以优先级小到大的顺序排序的
import heapq

class priorityList(object):
    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]

if __name__ == '__main__':
    q = priorityList()
    q.push(5,2)
    q.push(3,1)
    q.push(7,1)
    print(q.pop())
    print(q._queue)

6.生成一对多字典

  • collections.defaultdict(type)会默认初始化字典key对应的值为“空”
from collections import defaultdict

d = defaultdict(list)
for key, value in pairs:
    d[key].append(value)

7.让字典保持有序

  • collections.OrderedDict()
from collections import OrderedDict
d = OrderedDict()
##然后当字典用

8.与字典有关的计算问题

  • zip(list1,list2)生成一个迭代器内容为list1与list2组合成的元组
min(zip(d.values(), d.keys()))
max(zip(d.values(), d.keys()))

9.两个字典的相同点

  • dict.keys()返回keys-view对象
  • dict.items()返回item-view对象
  • 以上的对象可以进行集合操作 交集 |,差集 -,并集 &
a = {'a':1,'b':2}
c = {key:a[key] for key in a.keys() - ('b')}
# 字典解析

10.序列去重并顺序不变

  • set()集合
  • yield
  • lambda
def depute(items, key=None):
    s = set()
    for item in items:
        val = item if key == None else key(item)
        if val not in s:
            yield item
            s.add(val)

c = [{'x':1,'y':2},{'x':1, 'y':3},{'x':2, 'y':3}]
print(list(depute(c, lambda d:(d['x']))))

11.对切片命名

  • slice()可用于切片操作
PRICE = slice(2,4)
record = 'AA123456567899'
cost = int(record[PRICE]) * 2

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

  • collections.Counter()
words = ['i','am','i']
word_counts = Counter(words)
print(word_counts.most_common(3))
word_counts['i'] += 1
morewords = ['i','was']
word_counts.update(morewords)

13.通过公共键堆字典列表排序

  • operator.itemgetter
from operator import itemgetter
sorted(d, key=itemgetter('lname'))

14.对不原生支持比较的对象排序

  • sort的key参数
  • lambda
  • operator.attrgetter()

15.根据字段将字典列表分组

  • itertools.groupby() and sort()
  • collections.defaultdict()
from operator import itemgetter
from itertools import groupby

rows.sort(key=itemgetter('date'))
for date, items in groupby(rows, key=itemgetter('date')):
    for i in items:
        print(i)

16.筛选序列的元素

  • 列表推导式[ n if n>10 else 0 for n in xrange(20)]
  • 生成器表达式(n if n>10 else 0 for n in xrange(20))
  • filter(function, list)
  • itertools.compress(可迭代对象, 布尔序列)

17.从字典中提取子集

  • 字典推导式{key:value for key,value in prices.items() if value > 200}

18.将名称映射到序列的元素中

  • collections.namedtuple()命名元组
from collections import namedtuple

Subscribe = namedtuple('Subscribe',['addr', 'joined'])
sub = Subscribe('openex@qq.com','2016/1/1')
sub = sub._replace(joined=2) 
print(sub.addr)
print(sub.joined)

19.同时对数据做转换和换算

  • 在函数参数中使用生成器表达式(函数指sum(),min()等可传入迭代元素函数)
  • 注意max(生成器表达式) 比 max( [生成器表达式] ) 省内存
d= [{'name':'kevin', 'price':1},{'name':"openex", 'price':2}]
print(max(s['price'] * 2 for s in d))
###输出: 4
print(max(d, key=lambda s:s['price'] * -1) )
###输出: {'name': 'kevin', 'price': 1}

20.将多个字典映射为一个字典

  • collections.ChainMap(*maps)
  • map.update(map)
  • ChainMap,在修改和查询时默认操作第一个字典
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容