• python cookbook第三版学习笔记 一


    数据结构

    假设有M个元素的列表,需要从中分解出N个对象,N<M,这会导致分解的值过多的异常。如下:

    record=['zhf','zhf@163.com','775-555-1212','847-555-1212']
    name,email,=record

    E:python2.7.11python.exe E:/py_prj/python_cookbook.py

    Traceback (most recent call last):

      File "E:/py_prj/python_cookbook.py", line 9, in <module>

        name,email,=record

    ValueError: too many values to unpack

    提示too many values to unpack

    在python3中可以用*表达式来解决

    record=['zhf','zhf@163.com','775-555-1212','847-555-1212']
    name,email,*phone_number=record
    此时name=’zhf’,email=’zhf@163.com’
    Phone_number=['775-555-1212','847-555-1212']
    但是此类用法仅限于3.0. 2.7.6版本会报错
     
    (二)
    保存最后N个元素:
    有的时候我们希望保存查找到元素的最后前5个元素,比如文件有如下内容:
    This is a c test
    This is a java test
    This is a go test
    This is a c++ test
    This is a mysql test
    This is a javascript test
    This is a perl test
    This is a ruby test
    This is a python test
    This is a essamble test
    This is a linux test
    我们想找到This is a python test的前5个记录。我们可以用collections.deque来实现。 Deque(maxlen=N)创建了一个固定长度的队列,当有新记录加入队列而队列已满时会自动移除最老的记录。实现FIFO的功能。实现代码如下:
    def search(lines,pattern,history=5):
    #创建一个长度为5的队列
        previous_line=deque(maxlen=history)
        for line in lines:
            if pattern in line:
                yield line,previous_line
    #将查找到pattern之前的信息插入队列
            previous_line.append(line)

    if __name__=='__main__':
        f=open(r'E:py_prj est.txt')
        for line,previous in search(f,'python',5):
            for plines in previous:
    #打印出最后5条信息
                print plines
    #打印出查找到的pattern
            print line
    结果如下:previous保存了This is a python test的前5条信息
    E:python2.7.11python.exe E:/py_prj/python_cookbook.py
    This is a c++ test
     
    This is a mysql test
     
    This is a javascript test
     
    This is a perl test
     
    This is a ruby test
     
    This is a python test

    下面的例子更直观的表现了deque的功能,当达到最大数量的时候,删除最早的元素,然后在末端插入新的元素

    >>> from collections import deque

    >>> q=deque(maxlen=3)

    >>> q.append(1)

    >>> q.append(2)

    >>> q.append(3)

    >>> q

    deque([1, 2, 3], maxlen=3)

    >>> q.append(4)

    >>> q

    deque([2, 3, 4], maxlen=3)

    >>> q.append(5)

    >>> q

    deque([3, 4, 5], maxlen=3)

    如果不指定大小,那么则是无限大的队列,可以appendleft在左端插入元素,也可以用popleft来将最左边的出队列

    >>> q=deque()

    >>> q.append(1)

    >>> q.append(2)

    >>> q.append(3)

    >>> q.appendleft(4)

    >>> q

    deque([4, 1, 2, 3])

    >>> q.popleft()

    4

    三 找到最大的N个元素:

    Heapq模块有2个函数,nlargest()和nsmallest()可以解决这个问题

    import heapq
    nums=[1,8,2,10,4,5,6,19,20]
    largest=heapq.nlargest(3,nums)
    print largest

    得到结果:

    [20, 19, 10]

    [1, 2, 4]

    我们还可以导入更复杂的数据结构进行比较:如下面的结构。里面包含了6个元素,都是字典类型的。如何根据price对他们进行排序呢

    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}
    ]

    我们来看下heapq.nlargest的帮助手册。原型函数中第一个参数是返回的数目,第二个参数表明是可迭代对象。第三个参数key值默认为None

    Help on function nlargest in module heapq:

    nlargest(n, iterable, key=None)

        Find the n largest elements in a dataset.

       

        Equivalent to:  sorted(iterable, key=key, reverse=True)[:n]

    这个key值和sorted的key值是一个作用,这个key值指定可迭代对象中的一个元素来进行排序。也就是从第二个参数中接受一个参数进行处理,最后得到一个元素。函数会根据这个元素来进行排序。那么前面的例子中,每个迭代对象返回一个字典。那么key值的作用就是从这个字典中取出一个关键参数作为排序的参考。

    代码改造如下:使用lambda来实现这个函数功能。这个s值就是portfolio中返回的每个字典值。取出其中price字段进行排序

    largest=heapq.nlargest(3,portfolio,key=lambda s:s['price'])
    samllest=heapq.nsmallest(3,portfolio,key=lambda s:s['price'])

    结果如下:

    [{'price': 543.22, 'name': 'AAPL', 'shares': 50}, {'price': 115.65, 'name': 'ACME', 'shares': 75}, {'price': 91.1, 'name': 'IBM', 'shares': 100}]

    [{'price': 16.35, 'name': 'YHOO', 'shares': 45}, {'price': 21.09, 'name': 'FB', 'shares': 200}, {'price': 31.75, 'name': 'HPQ', 'shares': 35}]

    通过heapq的名字可以看出,这是将一个数据对象用堆排序并取得最大最小的值。具体是如何来实现的呢。我们首先来看下heapq.heapify这个函数

    nums=[1,8,2,10,4,5,6,19,20]
    heapq.heapify(nums)
    print nums

    结果如下:

    [1, 4, 2, 10, 8, 5, 6, 19, 20]

    其实heapfify就是生成一个最小堆的树型结构。具体最小堆的定义可以参考数据结构。最小堆就是子节点大于父节点。结构如下所示:

    1,8,2,10,4,5,6,19,20的树形结构如下

                         1

    8                  2

                   10   4  5  6

                 19   20

    排序后的数据结构,可以看到变动仅在于8和4,也就是将4上浮,8下沉。得到如下的结构。可以看到最顶端的父节点始终是最小的元素。

                         1

    4                         2

                 10     8  5    6

              19     20

    因此根据这个结构我们就可以用heapq.heappop(nums)得到最小的元素。其实每次heappop执行的过程都是一次堆重新排序的过程,自动将最小的元素排在父节点。整个执行过程如下:
    >>> nums=[1,8,2,10,4,5,6,19,20]
    #首先必须要用heapify将数据转换成堆的形式
    >>> heapq.heapify(nums)
    >>> nums
    [1, 4, 2, 10, 8, 5, 6, 19, 20]
                            1
                    4               2
              10         8     5         6
        19          20
    >>> heapq.heappop(nums)
    1
    >>> nums
    [2, 4, 5, 10, 8, 20, 6, 19]
                             2
                      4              5
               10            8   20       6
          19
    >>> heapq.heappop(nums)
    2
    >>> nums
    [4, 8, 5, 10, 19, 20, 6]
                               4
                       8               5
                10            19   20       6
    >>> heapq.heappop(nums)
    4
    >>> nums
    [5, 8, 6, 10, 19, 20]
                               5
                       8                6
                10            19    20
    >>> heapq.heappop(nums)
    5
    >>> nums
    [6, 8, 20, 10, 19]
                              6
                      8               20
              10              19
    >>> heapq.heappop(nums)
    6
    >>> nums
    [8, 10, 20, 19]
                              8
                       10            20
                19
    >>> heapq.heappop(nums)
    8
    >>> nums
    [10, 19, 20]
                                10
                         19               20
     
    >>> heapq.heappop(nums)
    10
    >>> nums
    [19, 20]
                                19
                          20
    >>> heapq.heappop(nums)
    19
    >>> nums
    [20]
    从上面的过程可以看到,其实每次heappop都是一次树型结构的调整,自动会将最小的元素上浮到父节点,
    上浮和下沉的具体实现函数如下,有兴趣的可以研究下。
    def _siftup(heap, pos):
        endpos = len(heap)
        startpos = pos
        newitem = heap[pos]
        # Bubble up the smaller child until hitting a leaf.
       
    childpos = 2*pos + 1    # leftmost child position
       
    while childpos < endpos:
            # Set childpos to index of smaller child.
           
    rightpos = childpos + 1
            if rightpos < endpos and not cmp_lt(heap[childpos], heap[rightpos]):
                childpos = rightpos
            # Move the smaller child up.
           
    heap[pos] = heap[childpos]
            pos = childpos
            childpos = 2*pos + 1
        # The leaf at pos is empty now.  Put newitem there, and bubble it up
        # to its final resting place (by sifting its parents down).
       
    heap[pos] = newitem
        _siftdown(heap, startpos, pos)

  • 相关阅读:
    Bootstrap中,模态框嵌套模态框时,关闭第二个模态框时,导致第一个模态框的滚动条消失
    heidisql 远程登录本地虚拟机中的 MariaDB
    ssh-keygen -t rsa -C "content" 解释
    IIS 环境 CodeIgniter 隐藏 URL 中的 index.php
    Windows 环境下 PHP 安装 xdebug 及配置
    win10 更新后主机背部音频输出无声音
    MySql.Data.MySqlClient.MySqlException: Packets larger than max_allowed_packet are not allowed
    关于 IIS 中 iconfont.woff 报 404(Not Found) 的原因即解决方法
    IIS Web API 长时间不连接后第一次访问非常缓慢
    VS Code 中 HTML 文档注释 js 语句异常
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/7056578.html
Copyright © 2020-2023  润新知