保留最后n个元素:

from collections import deque
def search (lines, pattern, history=):
previous_lines = deque(maxlen=history)
for li in lines:
if pattern in li:
yield li, previous_lines
previous_lines.append(li)
with open(r'chap1.txt') as f:
for line, prevlines in search(f, 'python', ):
for pline in prevlines:
print(pline, end='')
print(line, end='')
print('-' * )

chap1.txt

python1
python2
python3
python4
python5
python6
python7python
sfsfsfsdf python sdfsfs

q = deque(maxlen = 3)构造一个固定大小的队列,当队列满了最新的取代最先进入的。不定义maxlen会构造一个无限的队列。

 >>> q = deque()
 >>> q . append(1)
 >>> q . append(2)
 >>> q . append(3

>>> q.appendleft()
>>> q
deque([, , , ])
>>> q . pop() >>> q
deque([, , ])
>>> q . popleft()
4

查找最大或最小的N个元素

import heapq
portfolio = [
{'name': 'IBM', 'shares': , 'price': 91.1},
{'name': 'AAPL', 'shares': , 'price': 543.22},
{'name': 'FB', 'shares': , 'price': 21.09},
{'name': 'HPQ', 'shares': , 'price': 31.75},
{'name': 'YHOO', 'shares': , 'price': 16.35},
{'name': 'ACME', 'shares': , 'price': 115.65}
]
cheap = heapq.nsmallest(, portfolio, key=lambda s: s['price'])
expensive = heapq.nlargest(, portfolio, key=lambda s: s['price'])
print(cheap)
print(expensive)

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

如果只要最大最小,min(), max()方法最合适,如果n大小和list大小差不多,sorted(items)[:N] 或者是 sorted(items)[-N:]先排序后切片最合适。
heapq永远把最小的元素放在第一个元素

>>> nums = [, , , , , - , , , , , ]
>>> import heapq
>>> heapq.heapify(nums)
>>> nums
[-, , , , , , , , , , ]

获取最小3个元素

>>> heapq . heappop(nums)
-
>>> heapq . heappop(nums) >>> heapq . heappop(nums)

实现一个有优先级的队列

class PriorityQueue(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]
class Item(object):
def __init__ (self, name):
self.name = name
def __repr__ (self):
return 'Item({!r})'.format(self.name)
q = PriorityQueue()
q.push(Item('foo'), 1)
q.push(Item('bar'), 5)
q.push(Item('spam'), 4)
q.push(Item('grok'), 1)
print(q.pop())
print(q.pop())
print(q.pop())
print(q.pop())

(-priority, self._index, item))将这个元组push进队列,-priority保证正数最大的永远排在第一个位置。index保证如果优先级相同时按照index排序,如果不加这个index,优先级相同的item比较时会报错。
heapq.heappop(self._queue)[-1]   -1取的是元组中的最后一个也就是item。

一个字典映射多个值

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

这个是用来整洁下面这样的代码:

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

字典排序:

from collections import OrderedDict
import json
def ordered_dict():
d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
# Outputs "foo 1", "bar 2", "spam 3", "grok 4"
for k in d:
print(k, d[k])
print(json.dumps(d))
ordered_dict()

OrderDict按照插入顺序排序,精确控制以JSON编码后字段的顺序非常有用。但是OrderDict是普通字典的两倍,内部维护着一个另外一个链表。需要权衡。

普通字典的运算(最大值,最小值,排序)

def dict_sort_test():
prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
min_price = min(zip(prices.values(), prices.keys()))
print(min_price)
max_price = max(zip(prices.values(), prices.keys()))
print(max_price)
prices_sorted = sorted(zip(prices.values(), prices.keys()))
print(prices_sorted)
prices_and_names = zip(prices.values(), prices.keys())
print (min(prices_and_names))
# print (max(prices_and_names)) print(min(prices, key =lambda k: prices[k])) # Returns 'FB'
print(max(prices, key =lambda k: prices[k])) # Returns 'AAPL'
min_value = prices[min(prices, key =lambda k: prices[k])]
print(min_value)
dict_sort_test()

zip函数创建的是只能访问一次的迭代器。连续访问会报错:ValueError: max() arg is an empty sequence

查找两个字典的相同点

def dict_diff():
a = {
'x' : 1,
'y' : 2,
'z' : 3
}
b = {
'w' : 10,
'x' : 11,
'y' : 2
}
print(a.keys() & b.keys())
print(type(a.keys() & b.keys())) # <class 'set'>
print(a.keys() - b.keys())
print(a.items() & b.items())
c = {key:a[key] for key in a.keys() - {'z', 'w'}} #{'x': 1, 'y': 2}
dict_diff()

可以根据已有字典生成一个不包含某些键的字典

消除序列中相同元素并保持顺序

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)
a = [1, 5, 2, 1, 9, 1, 5, 10]
print(list(dedupe(a)))
a = [ {'x':1, 'y':2}, {'x':1, 'y':3}, {'x':1, 'y':2}, {'x':2, 'y':4}]
print(list(dedupe(a, key =lambda d: (d['x'],d['y']))))
print(list(dedupe(a, key =lambda d: d['x'])))

这个是保持了原顺序,如果不需要保持顺序只是简单的去重用set就可以了。

切片

def slice_test():
items = [0, 1, 2, 3, 4, 5, 6]
a = slice(2, 4)
print(items[2:4])
print(items[a])
s = 'HelloWorld' a = slice(5, 50, 2)
a.indices(len(s)) #(5, 10, 2)
for i in range(*a.indices(len(s))):
print (s[i])
slice_test()

值得注意的就是a定义了end为50,但实际字符串长度是10,用slice避免索引越界,会自动调整。

对单次的计数

from collections import Counter
def counter_test():
words = [
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
'my', 'eyes', "you're", 'under'
]
word_counts = Counter(words)
print(word_counts['neverthere'])
top_three = word_counts.most_common(3)
print (top_three)

# 对又增加的单次计数下面的两种方法任选其一
  morewords = ['why', 'are', 'you', 'not', 'looking', 'in', 'my', 'eyes']
# print(word_counts['eyes'])
# for word in morewords:
# word_counts[word] += 1
# print(word_counts['eyes']) print(word_counts['eyes'])
word_counts . update(morewords)
print(word_counts['eyes']) a = Counter(words)
b = Counter(morewords)
c = a + b
print(c)
d = a - b
print(d)
counter_test()

字典按关键字排序

from operator import itemgetter
def dict_sort_keyword_test():
rows = [
{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
# rows_by_fname = sorted(rows, key =lambda r: r['fname']) itemgetter会快些
rows_by_fname = sorted(rows, key=itemgetter('fname'), reverse=True)
print (rows_by_fname)
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print (rows_by_uid)
rows_by_lfname = sorted(rows, key=itemgetter('lname', 'fname'))
print (rows_by_lfname)
print(min(rows, key = itemgetter('uid'))['uid'])

对象的按照关键字比较

from operator import attrgetter
class User :
def __init__ (self, user_id):
self.user_id = user_id
def __repr__ (self):
return 'User({})'.format(self.user_id)
def sort_notcompare ():
users = [User(23), User(3), User(99)]
print(users)
print(sorted(users, key = attrgetter('user_id')))
print(sorted(users, key =lambda u: u . user_id))
sort_notcompare()

和上面类似attrgetter更快一些。同时支持多个字段的比较

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

通过某个字段将序列分组

rows = [
{'address': '5412 N CLARK', 'date': '07/01/2012', 'pid' : 7},
{'address': '5148 N CLARK', 'date': '07/04/2012', 'pid' : 2},
{'address': '5800 E 58TH', 'date': '07/02/2012', 'pid' : 5},
{'address': '2122 N CLARK', 'date': '07/03/2012', 'pid' : 6},
{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012', 'pid' : 8},
{'address': '1060 W ADDISON', 'date': '07/02/2012', 'pid' : 7},
{'address': '4801 N BROADWAY', 'date': '07/01/2012', 'pid' : 1},
{'address': '1039 W GRANVILLE', 'date': '07/04/2012', 'pid' : 1},
]

按照date排序并分组


from operator import itemgetter
from itertools import groupby
def group_by_keyword_sort():
rows.sort(key = itemgetter('date', 'pid'))
# Iterate in groups
for date, items in groupby(rows, key = itemgetter('date')):
print(date)
for i in items:
print(' ', i)

groupby()函数扫描整个序列并且查找连续相同值(或者根据指定key函数返回值相同)的元素序列。 在每次迭代的时候,它会返回一个值和一个迭代器对象, 这个迭代器对象可以生成元素值全部等于上面那个值的组中所有对象。所以在分组前一定要先排好序。可以实现多字段排序。

这是按照date排序了,如果不想排序,只是想放进一个大的dict里,根据key来获取最好用defaultdict

def group_by_keyword_no_sort():
from collections import defaultdict
rows_by_date = defaultdict(list)
for row in rows:
rows_by_date[row['date']].append(row)
for g in rows_by_date:
print(g)
for r in rows_by_date[g]:
print(' ',r)

从地点提取子字典

def sub_dict():
prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
p1 = {key: value for key, value in prices.items() if value > }
p2 = dict((key, value) for key, value in prices.items() if value > )
names = {'AAPL', 'IBM', 'HPQ'}
p3 = {key: value for key, value in prices.items() if key in names}
p4 = {key: prices[key] for key in prices.keys() & names}

使用哪种方法根据自己习惯,p1比p2快些,p3比p4快些。

映射名称到序列元素

def nametuple_test():
from collections import namedtuple
Subscriber = namedtuple('Subscriber', ['addr', 'joined'])
sub = Subscriber('fzk@example.com', '2017-03-21')
print(sub.addr)
print(sub.joined)

命名元祖的一个主要用途是从代码的下标解脱出来,如查询数据库。

from collections import namedtuple
Stock = namedtuple('Stock', ['name', 'shares', 'price'])
def compute_cost (records):
total = 0.0
for rec in records:
s = Stock(*rec)
total += s.shares * s.price
return total

命名元祖的另外一个用途是作为字典的替代。但是命名元祖是不可修改的,如果需要修改用_replace()创建一个新元祖,如果经常需要修改,那么命名元祖并不合适。

sub = sub._replace(joined='2017-03-22')

可以创建一个包含缺省值的原型元祖,然后使用_replace()方法创建新的值被更新过的实例。

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

转换并同时计算数据

nums = [1, 2, 3, 4, 5]
s = sum(x * x for x in nums)

python cookbook 数据结构的更多相关文章

  1. Python Cookbook 数据结构和算法

    1.查找最大或最小的N个元素 import heapq nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2] print(heapq.nlargest(3, n ...

  2. python书籍推荐:Python Cookbook第三版中文

    所属网站分类: 资源下载 > python电子书 作者:熊猫烧香 链接:http://www.pythonheidong.com/blog/article/44/ 来源:python黑洞网 内容 ...

  3. Python Cookbook(第3版) 中文版 pdf完整版|网盘下载内附提取码

    Python Cookbook(第3版)中文版介绍了Python应用在各个领域中的一些使用技巧和方法,其主题涵盖了数据结构和算法,字符串和文本,数字.日期和时间,迭代器和生成器,文件和I/O,数据编码 ...

  4. python 与数据结构

    在上面的文章中,我写了python中的一些特性,主要是简单为主,主要是因为一些其他复杂的东西可以通过简单的知识演变而来,比如装饰器还可以带参数,可以使用装饰类,在类中不同的方法中调用,不想写的太复杂, ...

  5. [0x00 用Python讲解数据结构与算法] 概览

    自从工作后就没什么时间更新博客了,最近抽空学了点Python,觉得Python真的是很强大呀.想来在大学中没有学好数据结构和算法,自己的意志力一直不够坚定,这次想好好看一本书,认真把基本的数据结构和算 ...

  6. Python -- 堆数据结构 heapq - I love this game! - 博客频道 - CSDN.NET

    Python -- 堆数据结构 heapq - I love this game! - 博客频道 - CSDN.NET Python -- 堆数据结构 heapq 分类: Python 2012-09 ...

  7. python cookbook学习1

    python cookbook学习笔记 第一章 文本(1) 1.1每次处理一个字符(即每次处理一个字符的方式处理字符串) print list('theString') #方法一,转列表 结果:['t ...

  8. 《Python cookbook》 “定义一个属性可由用户修改的装饰器” 笔记

    看<Python cookbook>的时候,第9.5部分,"定义一个属性可由用户修改的装饰器",有个装饰器理解起来花了一些时间,做个笔记免得二刷这本书的时候忘了 完整代 ...

  9. python实现数据结构单链表

    #python实现数据结构单链表 # -*- coding: utf-8 -*- class Node(object): """节点""" ...

随机推荐

  1. 【SpringMVC学习11】SpringMVC中的拦截器

    Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理.本文主要总结一下springmvc中拦截器是如何定义的,以及测试拦截器的执行情况和使用 ...

  2. Android下 布局加边框 指定背景色 半透明

    背景设置为自定义的shape文件: <!-- <?xml version="1.0" encoding="utf-8"?><shape ...

  3. DASH简介及使用方法(FFmpeg, MP4Box)

    DASH 为什么选择DASH YouTube采用DASH!其网页端及移动端APP都使用了DASH.DASH的其他采用者包括:Netflix, Hulu, … 什么是DASH 一种服务端.客户端的流媒体 ...

  4. background API

    语法: background:bg-color bg-image position/bg-size bg-repeat bg-origin bg-clip bg-attachment initial| ...

  5. Mysql-Proxy实现mysql读写分离、负载均衡 (转)

    在mysql中实现读写分离.负载均衡,用Mysql-Proxy是很容易的事,不过大型处理对于性能方面还有待提高,主要配置步骤如下: 1.1. mysql-proxy安装 MySQL Proxy就是这么 ...

  6. python 用win32修改注册表,修改打开IE浏览器的配置

    打开注册表:win+r, regedit,注册表的管理是按照文件夹的形式的. 注册表总共有五项: HKEY_CLASSES_ROOT 是HKEY_LOCAL_MACHINE\Software的子项,保 ...

  7. 常见Linux/Unix开发辅助命令什锦

    很多零碎命令集锦: 1. 怎样通过命令下载ftp文件 read -s -p "Your passwd: " Passwd; wget --user=YourUserName --p ...

  8. pycharm下: conda installation is not found ----一个公开的bug的解决方案

    pycharm  conda installation is not  found ----一个公开的bug的解决方案 pycharm+anaconda 是当前的主流的搭建方案,但是常出现上述问题. ...

  9. 成长这事儿,不可不说-------Day36

    事实上我一直都有一个观点,从我当年刚学抛物线那会就有:人生事实上就是一条轨迹,无非是一些点的集合.只是有些在低谷,有些在高峰,放形象了看,有些熠熠生辉,有些暗淡的几若消逝,有些人总喜欢回头数着过往的痕 ...

  10. poj 2367

    Genealogical tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3658   Accepted: 2433 ...