Python Cookbook 学习笔记 第一章Data Structures and Algorithms

今天学习完了一部分Cookbook书上的内容,做一个笔记。
一、问题:如何将一个N个元素的元组或者序列拆解成为N个变量。
解决:对于任何 iterable的对象,例如元组、列表、文件、迭代器、生成器都可以采用简单赋值操作来完成这个任务。唯一的要求是要求变量的个数与序列中的元素个数是匹配的。例如:

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

>>> name, shares, price, (year, mon, day) = data
>>> name
'ACME'
>>> year
2012
>>> mon
12
>>> day
21
>>>

如果数量不匹配,会出现ValueError的错误

如果想忽略序列中的特定位置上的元素,可以用_来标识。
例如:

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

二、对任意长度的序列进行拆包
问题:如何对一个你不知道长度或者序列长度较长的序列进行拆包操作
解决:使用运算符。运算符在python具有常见的运用,它使得很多操作变得更加灵活。
假设现在有一个有一个客户信息,包括姓名、E-mail和电话的信息,每个客户留的电话的数目可能是不一样的,现在我们需要对这个序列进行拆包操作,便于后面的处理。我们可以用*运算符

>>> record = ('Dave', '[email protected]', '773-555-1212', '847-555-1212')
>>> name,email,*phones = record
>>> name
'Dave'
>>> email
'[email protected]'
>>> phones
['773-555-1212', '847-555-1212']
>>> type(phones)
<class 'list'>
>>> 

从上面代码可知,*运算符的变量最后是一个列表的类型。
如果在拆包时不想要其中连续的一系列元素,可以用*_来表示。例如:

>>> record = ('ACME', 50, 123.45, (12, 18, 2012))
>>> name, *_, (*_, year) = record
>>> name
'ACME'
>>> year
2012
>>>

书中最后列举一个递归的应用:

>>> def sum(items):
... head, *tail = items
... return head + sum(tail) if tail else head
...
>>> sum(items)
36

作为开阔思路罗列在此

三、保存最后的N个元素
问题:在某些迭代处理中或者某些操作中保存最后的N个元素。
解决:运用collections模块中的deque类来实现队列的效果。假设现在有一个文件,需要找出含有某个模式的最后N行,代码如下:

>>> from collections import deque
>>> def search(pattern,lines,history = 5):
    preresult = deque(maxlen = history)
    for line in lines:
        if pattern in line:
            yield line,preresult
            preresult.append(line)

代码与原书略有不同,因为想实现的功能有细小的差别。
对于deque的功能可以手动实现,但是相对而言deque要快一些
对于deque类可以不指定maxlen,这时deque是无限长的,可以用append,appendleft,pop,popleft函数来添加或者弹出元素。这些操作的时间复杂度为O(1)
四、找最大或者最小的N个元素
问题:想要找到集合中最大或者最小的几个元素
解决:可以使用python中的 heapq模块来解决。heapq是对堆的模拟实现。其中有两个方法可以解决问题。heapq.nlargest(n, iterable, key=None)和 heapq.nsmallest(n, iterable, key=None) 。举例如下:

>>> import heapq
>>> nums = [32,42,423,13,133,4,3534,53,2]
>>> print(heapq.nlargest(3,nums))
[3534, 423, 133]
>>> print(heapq.nsmallest(3,nums))
[2, 4, 13]
>>> 
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.nlargest(3,portfolio,key = lambda x:x['price'])
>>>> print(cheap)
[{
  'name': 'AAPL', 'shares': 50, 'price': 543.22}, {
  'name': 'ACME', 'shares': 75, 'price': 115.65}, {
  'name': 'IBM', 'shares': 100, 'price': 91.1}]

heapq.nlargest(n, iterable, key=None)和 heapq.nsmallest(n, iterable, key=None)这两个函数在时间性能上有优势。
heapq.heapify(x) 函数可以在线性时间内将一个list转化为一个heap。
heapq模块实现的是小顶堆。模块中的函数如下:
heapq.heappush(heap, item)
Push the value item onto the heap, maintaining the heap invariant.

heapq.heappop(heap)
Pop and return the smallest item from the heap, maintaining the heap invariant. If the heap is empty, IndexError is raised. To access the smallest 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.heapify(x)
Transform list x into a heap, in-place, in linear time.

heapq.heapreplace(heap, item)
Pop and return the smallest item from the heap, and a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值