• Python collections模块


    整理自:博客 & Python中文

    常用的有:defaultdict、deque、Ccounter

    defaultdict 对象

    class collections.defaultdict([default_factory[, ...]])

    1)在有dict的情况下为何使用defaultdict:

    使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict

    2) default_factory如何设置:

    第一个参数 default_factory 提供了一个初始值。它默认为 None 。所有的其他参数都等同与 dict 构建器中的参数对待,包括关键词参数。我的理解是若不设置default_factory,则当查找一个不存在的键时,就会报错:

    >>> d = defaultdict()   # 没有初始化参数default_factory
    >>> d
    defaultdict(None, {})
    >>> d['a']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    KeyError: 'a'

    那么,default_factory可以取哪些可调用方法呢?有很多:   list,     set,     int,    lambda :None,     lambda :0 等等。

    • list
    • >>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
      >>> d = defaultdict(list)    # 对于不存在的键,返回list()
      >>> for k, v in s:
      ...     d[k].append(v)       # d[k]就是列表
      ...
      >>> sorted(d.items())
      [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
      >>> d = defaultdict(list)
      >>> d
      defaultdict(<class 'list'>, {})
      >>> d['a']     # 键‘a’不存在,则赋予空列表。相当于a=list()
      []
      >>> d
      defaultdict(<class 'list'>, {'a': []})     # 注意到‘a’虽不存在,但也被添加到字典里
    • set
    • >>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
      >>> d = defaultdict(set)   # set()
      >>> for k, v in s:
      ...     d[k].add(v)        # d[k]就是集合   
      ...
      >>> sorted(d.items())
      [('blue', {2, 4}), ('red', {1, 3})]
    • int
      >>> s = 'mississippi'
      >>> d = defaultdict(int)        # int()总是为0
      >>> for k in s:
      ...     d[k] += 1
      ...
      >>> sorted(d.items())
      [('i', 4), ('m', 1), ('p', 2), ('s', 4)]
    • lambda :None
    • >>> d = defaultdict(lambda : None)     # f = lambda : None. f()总是返回None.  这个例子就没有上面那么有实际意义
      >>> d['a']
      >>> d
      defaultdict(<function <lambda> at 0x0000025FF637F048>, {'a': None})
      >>> d['a']+4
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
    • lambda :0
    • >>> d = defaultdict(lambda : 0)         # f = lambda : 0. f()总是返回None. 这个例子其实和int()一样了  
      >>> d
      defaultdict(<function <lambda> at 0x0000025FF606A0D0>, {})
      >>> d['a']
      0
      >>> d['a']+=1
      >>> d
      defaultdict(<function <lambda> at 0x0000025FF606A0D0>, {'a': 1})

    deque 对象

    class collections.deque([iterable[, maxlen]])

    返回一个新的双向队列对象,从左到右初始化(用方法 append()) ,从 iterable (迭代对象) 数据创建。如果 iterable 没有指定,新队列为空。

    Deque队列是由栈或者queue队列生成的(发音是 “deck”,”double-ended queue”的简称)。Deque 支持线程安全,内存高效添加(append)和弹出(pop),从两端都可以,两个方向的大概开销都是 O(1) 复杂度。

    虽然 list 对象也支持类似操作,不过这里优化了定长操作和 pop(0) 和 insert(0, v) 的开销。它们引起 O(n) 内存移动的操作,改变底层数据表达的大小和位置。

    如果 maxlen 没有指定或者是 None ,deques 可以增长到任意长度。否则,deque就限定到指定最大长度。一旦限定长度的deque满了,当新项加入时,同样数量的项就从另一端弹出。限定长度deque提供类似Unix filter tail 的功能。它们同样可以用与追踪最近的交换和其他数据池活动。

    双向队列(deque)对象支持以下方法:

    最常用的不过:append, appendleft, extend, extendleft, pop, popleft

    >>> deq = deque(list(),5)
    >>> deq
    deque([], maxlen=5)
    >>> deq.append([1,2,3,4])
    >>> deq.append(0)
    >>> deq.append(0)
    >>> deq.append(0)
    >>> deq.append(0)
    >>> deq
    deque([[1, 2, 3, 4], 0, 0, 0, 0], maxlen=5)         # 因为设定了最大长度,所以再次添加6的时候,前端出队列
    >>> deq.append(6)
    >>> deq
    deque([0, 0, 0, 0, 6], maxlen=5)

    双向队列(deque)对象支持以下方法:

    append(x)

    添加 x 到右端。

    appendleft(x)

    添加 x 到左端。

    clear()

    移除所有元素,使其长度为0.

    copy()

    创建一份浅拷贝。

    3.5 新版功能.

    count(x)

    计算deque中个数等于 x 的元素。

    3.2 新版功能.

    extend(iterable)

    扩展deque的右侧,通过添加iterable参数中的元素。

    extendleft(iterable)

    扩展deque的左侧,通过添加iterable参数中的元素。注意,左添加时,在结果中iterable参数中的顺序将被反过来添加。

    index(x[, start[, stop]])

    返回第 x 个元素(从 start 开始计算,在 stop 之前)。返回第一个匹配,如果没找到的话,升起ValueError 。

    3.5 新版功能.

    insert(ix)

    在位置 i 插入 x 。

    如果插入会导致一个限长deque超出长度 maxlen 的话,就升起一个 IndexError 。

    3.5 新版功能.

    pop()

    移去并且返回一个元素,deque最右侧的那一个。如果没有元素的话,就升起 IndexError 索引错误。

    popleft()

    移去并且返回一个元素,deque最左侧的那一个。如果没有元素的话,就升起 IndexError 索引错误。

    remove(value)

    移去找到的第一个 value。 如果没有的话就升起 ValueError 。

    reverse()

    将deque逆序排列。返回 None 。

    deque 其他用法

    1. 过滤功能

    def tail(filename, n=10):
        'Return the last n lines of a file'
        with open(filename) as f:
            return deque(f, n)
    >>> s=[1,2,3,4,5,6]
    >>> deque(s,3)
    deque([4, 5, 6], maxlen=3)

    文档里还有一些稍微复杂的例子。下面是python中栈和队列的另一种表现

    栈直接用列表实现:

    The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved (“last-in, first-out”). To add an item to the top of the stack, use append(). To retrieve an item from the top of the stack, use pop() without an explicit index. For example:

    >>> stack = [3, 4, 5]
    >>> stack.append(6)
    >>> stack.append(7)
    >>> stack
    [3, 4, 5, 6, 7]
    >>> stack.pop()
    7
    >>> stack
    [3, 4, 5, 6]
    >>> stack.pop()
    6
    >>> stack.pop()
    5
    >>> stack
    [3, 4]

    队列就是上面的deque:(列表插入或删除都太低效了,所以用双向队列来实现)

    It is also possible to use a list as a queue, where the first element added is the first element retrieved (“first-in, first-out”); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).

    To implement a queue, use collections.deque which was designed to have fast appends and pops from both ends. For example:

    >>> from collections import deque
    >>> queue = deque(["Eric", "John", "Michael"])
    >>> queue.append("Terry")           # Terry arrives
    >>> queue.append("Graham")          # Graham arrives
    >>> queue.popleft()                 # The first to arrive now leaves
    'Eric'
    >>> queue.popleft()                 # The second to arrive now leaves
    'John'
    >>> queue                           # Remaining queue in order of arrival
    deque(['Michael', 'Terry', 'Graham'])

    Counter 对象

    一个计数器工具提供快速和方便的计数。比如

    >>> # Tally occurrences of words in a list
    >>> cnt = Counter()
    >>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
    ...     cnt[word] += 1
    >>> cnt
    Counter({'blue': 3, 'red': 2, 'green': 1})

    class collections.Counter([iterable-or-mapping])

    一个 Counter 是一个 dict 的子类,用于计数可哈希对象。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数。 Counter 类有点像其他语言中的 bags或multisets。

    元素从一个 iterable 被计数或从其他的 mapping (or counter)初始化:

    >>> c = Counter()                           # a new, empty counter
    >>> c = Counter('gallahad')                 # a new counter from an iterable
    >>> c = Counter({'red': 4, 'blue': 2})      # a new counter from a mapping
    >>> c = Counter(cats=4, dogs=8)             # a new counter from keyword args

    Counter对象有一个字典接口,如果引用的键没有任何记录,就返回一个0,而不是弹出一个 KeyError :

    >>> c = Counter(['eggs', 'ham'])
    >>> c['bacon']                              # count of a missing element is zero
    0

    设置一个计数为0不会从计数器中移去一个元素。使用 del 来删除它:

    >>> c['sausage'] = 0                        # counter entry with a zero count
    >>> del c['sausage']                        # del actually removes the entry
  • 相关阅读:
    前端性能优化(css动画篇)
    常用的布局及技巧
    一些有用的技能点
    做webApp遇到的一些坑及解决方案
    mysql5.7.30 编译安装
    windows使用Pandoc将Markdown转换为PDF文件
    源码编译安装keepalived
    源码编译php
    源码编译nginx
    源码编译PHP提示zip错误
  • 原文地址:https://www.cnblogs.com/king-lps/p/10625617.html
Copyright © 2020-2023  润新知