collections 模块

collections 模块

namedtuple

​ namedtuple创建一个和tuple类似的对象,而且对象拥有可访问的属性

  • 用nemedtuple 表示坐标

    from collections import namedtuple
    
    point = namedtuple('Point', ['x', 'y'])
    a = point(1, 2)
    >>> print(a.x)  # 即可以访问属性
    1
    >>> print(a)
    Point(x=1, y=2)
    
    point = namedtuple('Point', ['x', 'y', 'z'])
    b = point(1, 2, 3)
    >>> b
    Point(x=1, y=2, z=3)
    
    # 特殊用法
    >>> b = b._replace(x=2)
    >>> b
    Point(x=2, y=2, z=3)
    
    >>> b._asdict()
    {'x': 2, 'y': 2, 'z': 3}
    
  • 类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

    #namedtuple('名称', [属性list]):
    Circle = namedtuple('Circle', ['x', 'y', 'r'])
    
  • 举例:

    from collections import namedtuple
     
    # 定义一个namedtuple类型User,并包含name,sex和age属性。
    User = namedtuple('User', ['name', 'sex', 'age'])
     
    # 创建一个User对象
    user = User(name='kongxx', sex='male', age=21)
     
    # 也可以通过一个list来创建一个User对象,这里注意需要使用"_make"方法
    user = User._make(['kongxx', 'male', 21])
     
    print user
    # User(name='user1', sex='male', age=21)
     
    # 获取用户的属性
    print user.name
    print user.sex
    print user.age
     
    # 修改对象属性,注意要使用"_replace"方法
    user = user._replace(age=22)
    print user
    # User(name='user1', sex='male', age=21)
     
    # 将User对象转换成字典,注意要使用"_asdict"
    print user._asdict()
    # OrderedDict([('name', 'kongxx'), ('sex', 'male'), ('age', 22)])
    

deque

​ 使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。

​ deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:

  • 双端队列, "double-end queue"的简称

    from collections import deque
    
    q = deque(['a', 'b', 'c'])
    q.append('y')
    q.appendleft('x')
    
    >>> q
    deque(['y', 'a', 'b', 'c', 'x'])
    
    # deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
    
  • 其他方法

    # rotate(n)
    # rotate(n), 从右侧反转n步,如果n为负数,则从左侧反转。
    # d.rotate(1) 等于 d.appendleft(d.pop())
    
    from collections import deque
    
    st = "abbcd"
    dst = deque(st)
    dst.rotate(1)
    print(dst)
    #结果:
    #deque(['d', 'a', 'b', 'b', 'c'])
    
    # maxlen
    # 只读的属性,deque限定的最大长度,如果无,就返回None。
    # 当限制长度的deque增加超过限制数的项时, 另一边的项会自动删除。
    from collections import deque
    
    dst = deque(maxlen=2)
    dst.append(1)
    dst.append(2)
    print(dst)
    dst.append(3)
    print(dst)
    print(dst.maxlen)
    #结果:
    #deque([1, 2], maxlen=2)
    #deque([2, 3], maxlen=2)
    #2
    

OrderedDict

​ 使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。

如果要保持Key的顺序,可以用OrderedDict

  • 有序字典

    from collections import OrderedDict
    
    d = dict([('a', 1), ('b', 2), ('c', 3)])
    >>> d # dict的Key是无序的
    {'a': 1, 'c': 3, 'b': 2}
    
    od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    >>> od # OrderedDict的Key是有序的
    OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    
  • 获取键值

```python
# 注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

from collections import OrderedDict
od = OrderedDict()
od['z'] = 1
od['x'] = 2
od['y'] = 3

>>> od.keys()
['z', 'y', 'x']
```
  • 排序

    dd = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
    # 按key排序
    kd = collections.OrderedDict(sorted(dd.items(), key=lambda t: t[0]))
    >>> print(kd)
    OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
    
    # 按照value排序
    vd = collections.OrderedDict(sorted(dd.items(),key=lambda t:t[1]))
    >>> print(vd)
    OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
    

defaultdict

  • 用法

    有如下值集合 [11,22,33,44,55,66,77,88,99,90…],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。

    即: {‘k1’: 大于66 , ‘k2’: 小于66}

    # 原dict方法
    values = [11, 22, 33,44,55,66,77,88,99,90]
    
    my_dict = {}
    
    for value in  values:
        if value>66:
            if my_dict.has_key('k1'):
                my_dict['k1'].append(value)
            else:
                my_dict['k1'] = [value]
        else:
            if my_dict.has_key('k2'):
                my_dict['k2'].append(value)
            else:
                my_dict['k2'] = [value]
    
    # defaultdict 字典解决方法
    from collections import defaultdict
    
    values = [11, 22, 33,44,55,66,77,88,99,90]
    
    my_dict = defaultdict(list)
    
    for value in  values:
        if value>66:
            my_dict['k1'].append(value)
        else:
            my_dict['k2'].append(value)
    
  • 使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict

    >>> from collections import defaultdict
    >>> dd = defaultdict(lambda: 'N/A')
    >>> dd['key1'] = 'abc'
    >>> dd['key1'] # key1存在
    'abc'
    >>> dd['key2'] # key2不存在,返回默认值
    'N/A'
    

Counter

  • Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

    form collections import Counter
    c = Counter('abcdeabcdabcaba')
    >>> print(c)
    Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
    
  • 计数器更新(update, subtract)

    可以使用一个iterable对象或者另一个Counter对象来更新键值。

    计数器的更新包括增加和减少两种。

    # 其中,增加使用update()方法:
    from collections import Counter
    
    c = Counter('which')
    c.update('witch')  # 使用另一个iterable对象更新
    >>> c['h']
    3
    
    d = Counter('watch')
    c.update(d)  # 使用另一个Counter对象更新
    >>> c['h']
    4
    
    # 减少则使用subtract()方法:
    >>> c = Counter('which')
    >>> c.subtract('witch')  # 使用另一个iterable对象更新
    >>> c['h']
    1
    >>> d = Counter('watch')
    >>> c.subtract(d)  # 使用另一个Counter对象更新
    >>> c['a']
    -1
    
  • 键的删除

    当计数值为0时,并不意味着元素被删除,删除元素应当使用del

    c = Counter("abcdcba")
    >>> c
    Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
    
    c["b"] = 0
    >>> c
    Counter({'a': 2, 'c': 2, 'd': 1, 'b': 0})
    
    del c["a"]
    >>> c
    Counter({'c': 2, 'b': 2, 'd': 1})
    
  • 元素生成

    返回一个迭代器。元素被重复了多少次,在该迭代器中就包含多少个该元素。元素排列无确定顺序,个数小于1的元素不被包含。

    c = Counter(a=4, b=2, c=0, d=-2)
    >>> list(c.elements())
    ['a', 'a', 'a', 'a', 'b', 'b']
    
  • 找出TopN

    返回一个TopN列表。如果n没有被指定,则返回所有元素。当多个元素计数值相同时,排列是无确定顺序的。

    c = Counter('abracadabra')
    >>> c.most_common()
    [('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
    
    >>> c.most_common(3)
    [('a', 5), ('r', 2), ('b', 2)] 
    
  • 其他常用操作

    下面是一些Counter类的常用操作,来源于Python官方文档

    sum(c.values())  # 所有计数的总数
    c.clear()  # 重置Counter对象,注意不是删除
    list(c)  # 将c中的键转为列表
    set(c)  # 将c中的键转为set
    dict(c)  # 将c中的键值对转为字典
    c.items()  # 转为(elem, cnt)格式的列表
    Counter(dict(list_of_pairs))  # 从(elem, cnt)格式的列表转换为Counter类对象
    c.most_common()[:-n:-1]  # 取出计数最少的n个元素
    c += Counter()  # 移除0和负值
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江某指点迷津

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值