美文网首页
python模块---collections

python模块---collections

作者: kevin_lln | 来源:发表于2022-02-27 22:25 被阅读0次
              劝学
           颜真卿〔唐代〕
    
    三更灯火五更鸡,正是男儿读书时。
    黑发不知勤学早,白首方悔读书迟。
    

    collections是python内置的模块,提供常用的方法有namedtuple,defaultdict,deque,Counter,OrderedDict,ChainMap。

    1. namedtuple

    1.1 tuple

    在学些namedtuple先来看看python的tuple。

    • tuple是不可变的,可迭代的
    • 支持拆包
    name_tuple = ('kevin', 'man', 18)
    name, gender, age = name_tuple
    print(name, gender, age)
    name, *other = name_tuple
    print(name, other, type(other))
    # 结果
    # kevin man 18
    # kevin ['man', 18] <class 'list'>
    
    • tuple不可变性不是绝对的;
    name_tuple = ('kevin', [18, 19])
    name_tuple[1].append(20)
    print(name_tuple)
    # 结果
    # ('kevin', [18, 19, 20])
    
    

    tuple比list好的地方:immutable(不可变)的重要性,

    • 性能优化(指出元素全部为immutable的tuple会作为常量的编译时确定,因此产生了如此显著的速度差异)
    • 线程安全
    • 可以作为dict的key
    • 拆包特性

    1.2 namedtuple

    • namedtuple函数所创建(返回)的是一个 元组的子类
    • namedtuple函数所创建元组,中文名称为 具名元组

    namedtuple和tuple创建元组的区别

    • 使用namedtuple,我们既可以使用index来访问,也可以使用具名元组中每个字段的名称来访问;在使用普通元组的时候,我们只能通过index来访问元组中的某个数据
    • namedtuple省空间,内存效率高(数据处理)
    User = namedtuple("User", ['name', 'age', 'height', 'edu'])
      # 1.直接构造User对象,不需要完整的参数
    # 传入tuple
    user_tuple = ('kevin', 18, 175)
    user = User(*user_tuple, 'master')
    
    # 传入dict
    user_dict = {
        'name': 'kevin',
        'age': 18,
        'height': 175
    }
    user = User(**user_dict, edu='master')
    
    # 2.使用_make方法构建
    # 需要完整的参数,传入的参数是iterable(list,dict都可以)
    User._make(user_tuple)
    
    # 拆包
    name, age, *other = user
    print(name, age, other)
    
    # 转化为OrderDict
    user_info_dict = user._asdict()
    
    

    2. defaultdict

    defaultdict是实现的 dict 的一个子类,一般的dict会导致KeyError异常,而defaultdict可以避免KeyError异常。

    user_dict = {}
    user_list = ['kevin1', 'kevin2', 'kevin1', 'kevin2', 'kevin1', 'kevin2', 'kevin3']
    
    # 版本一:
    for user in user_list:
        if user not in user_dict:
            user_dict[user] = 1
        else:
            user_dict[user] += 1
    
    # 版本二:比版本一更佳高效
    for user in user_list:
        user_dict.setdefault(user, 0)
        user_dict[user] += 1
    
    # 版本三:代码最少,最不容易出错
    user_default_dict = defaultdict(int)
    for user in user_list:
        user_default_dict[user] += 1
    
    

    当想初始化更复杂的数据的时候,可以定义函数返回值

    def generate_dict():
        return {
            'name': 'kevin',
            'age': 18
        }
    test_dict = defaultdict(generate_dict)
    print(test_dict['kevin'])
    print(test_dict)
    # 结果
    # {'name': 'kevin', 'age': 18}
    # defaultdict(<function generate_dict at 0x109223560>, {'kevin': {'name': 'kevin', 'age': 18}})
    
    

    3. deque

    deque模块提供了两端都可以操作的序列,在序列的前后都可以执行添加或删除操作。deque GIL线程安全的,list不是安全线程的。底层是c语言写的,性能好。

    常用的方法:

    # 1.appendleft()
    user_list = deque(['kevin', 'kevin1', 'kevin2'])
    
    user_list.appendleft('kevin3')
    print(user_list)
    # 结果
    # deque(['kevin3', 'kevin', 'kevin1', 'kevin2'])
    
    # 2.copy() 此处为浅拷贝
    user_list1 = deque(['kevin', ['kevin1', 'kevin2', 'kevin3'], 'kevin2'])
    user_list2 = user_list1.copy()
    user_list1.append('kevin3')
    print(id(user_list1), id(user_list2))
    print(user_list1, user_list2)
    
    # 结果
    # 4391470368 4392448640
    # deque(['kevin', ['kevin1', 'kevin2', 'kevin3'], 'kevin2', 'kevin3']) deque(['kevin', ['kevin1', 'kevin2', 'kevin3'], 'kevin2'])
    user_list1[1].append('kevin4')
    print(user_list1, user_list2)
    # 结果,修改原数据第二个元素列表中的值,两个deque对象都改变
    # deque(['kevin', ['kevin1', 'kevin2', 'kevin3', 'kevin4'], 'kevin2', 'kevin3']) deque(['kevin', ['kevin1', 'kevin2', 'kevin3', 'kevin4'], 'kevin2'])
    
    # 3.extend() 返回值为None,直接在user_list叠加
    user_list.extend(user_list1)
    print(user_list)
    # 结果
    # deque(['kevin3', 'kevin', 'kevin1', 'kevin2', 'kevin', ['kevin1', 'kevin2', 'kevin3', 'kevin4'], 'kevin2', 'kevin3'])
    
    

    4. Counter

    Counter 是实现的 dict 的一个子类,可以用来方便地计数。

    from collections import Counter
    
    user_list = ['kevin1', 'kevin2', 'kevin1', 'kevin2', 'kevin1', 'kevin2', 'kevin3']
    
    user_counter = Counter(user_list)
    print(user_counter)
    
    # 结果
    # Counter({'kevin1': 3, 'kevin2': 3, 'kevin3': 1})
    
    

    常用的使用方法

    # 1.update()
    count1 = Counter('wleflwjflsjgl')
    count2 = Counter('jljlfsjlgsjlglsgjgls')
    count1.update(count2)
    print(count1)
    
    # 结果
    # Counter({'l': 10, 'j': 7, 's': 5, 'g': 5, 'f': 3, 'w': 2, 'e': 1})
    
    # 2.most_common() top n的问题
    top2 = count1.most_common(2)
    print(top2)
    
    top3 = count1.most_common(3)
    print(top3)
    # 结果
    # [('l', 10), ('j', 7)]
    # [('l', 10), ('j', 7), ('s', 5)]
    
    

    5. OrderedDict

    很多人认为python中的字典是无序的,其实python3中dict是有序的,在python2中dict是无序的。OrderedDict继承dict,dict有的方法,OrderedDict也能用。OrderedDict实现了对字典对象中元素的排序。请看下面示例:

    from collections import OrderedDict
    
    order_dict = OrderedDict()
    order_dict['b'] = 'kevin2'
    order_dict['c'] = 'kevin3'
    order_dict['a'] = 'kevin1'
    print(order_dict)
    # 结果
    # OrderedDict([('b', 'kevin2'), ('c', 'kevin3'), ('a', 'kevin1')])
    
    

    常用的方法

    # 1.popitem() 弹出最后一个键值对,并把原字典的最后一个元素删除
    print(order_dict.popitem())
    print(order_dict)
    # 结果
    # ('a', 'kevin1')
    # OrderedDict([('b', 'kevin2'), ('c', 'kevin3')])
    
    # 2.pop() 删除指定key,弹出value
    print(order_dict.pop('a'))
    print(order_dict)
    # 结果
    # kevin1
    # OrderedDict([('b', 'kevin2'), ('c', 'kevin3')])
    
    # 3.move_to_end(key) 根据传入的key,把这一键值对移动到最后
    order_dict.move_to_end('c')
    print(order_dict)
    # 结果
    # OrderedDict([('b', 'kevin2'), ('a', 'kevin1'), ('c', 'kevin3')])
    
    

    6. ChainMap

    ChainMap类用于快速链接多个字典(Dict),以便将它们视为一个单元。它通常比创建新字典和多次调用update()快得多。

    from collections import ChainMap
    
    user_dict1 = {'a': 'kevin1', 'b': 'kevin2'}
    user_dict2 = {'c': 'kevin2', 'd': 'kevin4'}
    
    new_dict = ChainMap(user_dict1, user_dict2)
    for k, v in new_dict.items():
        print(k, v)
    # 结果
    # c kevin2
    # d kevin4
    # a kevin1
    # b kevin2
    
    

    如果多个字典有相同的key,使用ChainMap的时候只会取第一次。请看如下示例:

    from collections import ChainMap
    
    user_dict1 = {'a': 'kevin1', 'b': 'kevin2'}
    user_dict2 = {'b': 'kevin2', 'd': 'kevin4'}
    
    # 如果有相同的key,遍历只取一次
    new_dict = ChainMap(user_dict1, user_dict2)
    for k, v in new_dict.items():
        print(k, v)
    # 结果
    # b kevin2
    # d kevin4
    # a kevin1
    
    

    修改ChainMap中的某个值

    print(new_dict)
    new_dict.maps[0]['b'] = 'kevin'
    print(new_dict)
    # 结果
    # ChainMap({'a': 'kevin1', 'b': 'kevin2'}, {'c': 'kevin2', 'd': 'kevin4'})
    # ChainMap({'a': 'kevin1', 'b': 'kevin'}, {'c': 'kevin2', 'd': 'kevin4'})
    
    

    user = User(*user_tuple, 'master')

    User._make(user_tuple)Î

    相关文章

      网友评论

          本文标题:python模块---collections

          本文链接:https://www.haomeiwen.com/subject/afjkrrtx.html