>> for word in set(word_list):... print(wor">
当前位置:   article > 正文

Python 的 collections 模块强化数据结构

Python 的 collections 模块强化数据结构

collections 是 Python 内建的一个集合模块,提供了许多有用的集合类。包括许多常见的强化数据结构类。至于为什么会出现强化数据结构,自然是因为一般的 元组、字典等可能不太满足一些特定的需要。

Counter

列表元素统计

普通实现

  1. >>> word_list = ["a", "b", "c", "c", "a", "a"]
  2. >>> cnt = {}
  3. >>> for word in set(word_list):
  4. ... cnt[word] = word_list.count(word)
  5. ...
  6. >>> cnt
  7. {'b': 1, 'c': 2, 'a': 3}
  8. >>> cnt['d']
  9. Traceback (most recent call last):
  10. File "<stdin>", line 1, in <module>
  11. KeyError: 'd'

Counter 实现 

  1. >>> from collections import Counter
  2. >>> cnt = Counter()
  3. >>> word_list = ['a', 'b', 'c', 'c', 'a', 'a']
  4. >>> for word in word_list:
  5. ... cnt[word] += 1
  6. ...
  7. >>> cnt
  8. Counter({'a': 3, 'c': 2, 'b': 1})
  9. >>> cnt['a']
  10. 3
  11. >>> cnt['d'] # 即使没有 key,也不会报 KeyError 哟,这点和 defaultdict(int) 比较像。
  12. 0

字符串字符统计

普通实现

  1. >>> word_str = 'hello world'
  2. >>> word_list = list(word_str)
  3. >>> cnt = {}
  4. >>> for word in set(word_list):
  5. ... cnt[word] = word_list.count(word)
  6. ...
  7. >>> cnt
  8. {'e': 1, 'd': 1, 'h': 1, 'o': 2, 'l': 3, ' ': 1, 'r': 1, 'w': 1}

Counter 实现

  1. >>> from collections import Counter
  2. >>> word_str = 'hello world'
  3. >>> cnt = Counter(word_str)
  4. >>> cnt
  5. Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
  6. >>> Counter({'red': 4, 'blue': 2})
  7. Counter({'red': 4, 'blue': 2})
  8. >>> Counter(red=4, blue=2)
  9. Counter({'red': 4, 'blue': 2})

Counter.elements()

  1. >>> cnt = Counter(red=4, blue=2)
  2. >>> cnt
  3. Counter({'red': 4, 'blue': 2})
  4. >>> list(cnt.elements())
  5. ['red', 'red', 'red', 'red', 'blue', 'blue']

Counter.most_common()

  1. >>> cnt = Counter('hello world')
  2. >>> cnt
  3. Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
  4. >>> cnt.most_common()
  5. [('l', 3), ('o', 2), ('h', 1), ('e', 1), (' ', 1), ('w', 1), ('r', 1), ('d', 1)]
  6. >>> cnt.most_common(3)
  7. [('l', 3), ('o', 2), ('h', 1)]

Counter.subtract()

  1. >>> a = Counter(a=4, b=2, c=0, d=-2)
  2. >>> a
  3. Counter({'a': 4, 'b': 2, 'c': 0, 'd': -2})
  4. >>> b = Counter(a=1, b=2, c=-3, d=4)
  5. >>> b
  6. Counter({'d': 4, 'b': 2, 'a': 1, 'c': -3})
  7. >>> a.subtract(b)
  8. >>> a
  9. Counter({'a': 3, 'c': 3, 'b': 0, 'd': -6})

常用操作

其实转换成 Counter 类型以后,操作和字典差不多。

  1. >>> from collections import Counter
  2. >>> cnt = Counter('hello world')
  3. >>> cnt
  4. Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
  5. >>> cnt.keys()
  6. dict_keys(['h', 'e', 'l', 'o', ' ', 'w', 'r', 'd'])
  7. >>> cnt.values()
  8. dict_values([1, 1, 3, 2, 1, 1, 1, 1])
  9. >>> sum(cnt.values())
  10. 11
  11. >>> dict(cnt)
  12. {'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1}
  13. >>> cnt.items()
  14. dict_items([('h', 1), ('e', 1), ('l', 3), ('o', 2), (' ', 1), ('w', 1), ('r', 1), ('d', 1)])
  15. >>> Counter(dict([('a', 1), ('b', 2), ('c', 3)]))
  16. Counter({'c': 3, 'b': 2, 'a': 1})
  17. >>> cnt.clear()
  18. >>> cnt
  19. Counter()

deque

deque 是栈和队列的一种广义实现,俗称双端队列。有效内存地以近似 O(1) 的性能在 deque 的两端插入和删除元素,尽管 list 也支持相似的操作,但是在 pop(0) 和 insert(0,v)(会改变数据的位置和大小)上有O(n)的时间复杂度。如果抛却这些细节不顾的话,你把他当成加强版的 list 好像也没啥毛病。

  1. >>> from collections import deque
  2. >>>
  3. >>> d = deque(['a', 'b', 'c'])
  4. >>> d
  5. deque(['a', 'b', 'c'])
  6. >>> d.append('d')
  7. >>> d
  8. deque(['a', 'b', 'c', 'd'])
  9. >>> d.count('b')
  10. 1
  11. >>> d.extend(['e', 'f', 'g'])
  12. >>> d
  13. deque(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
  14. >>> d.pop()
  15. 'g'
  16. >>> d
  17. deque(['a', 'b', 'c', 'd', 'e', 'f'])
  18. >>> d.remove('d')
  19. >>> d
  20. deque(['a', 'b', 'c', 'e', 'f'])
  21. >>> d.reverse()
  22. >>> d
  23. deque(['f', 'e', 'c', 'b', 'a'])
  24. # 队列左端操作
  25. >>> d
  26. deque(['f', 'e', 'c', 'b', 'a'])
  27. >>> d.popleft()
  28. 'f'
  29. >>> d
  30. deque(['e', 'c', 'b', 'a'])
  31. >>> d.appendleft('h')
  32. >>> d
  33. deque(['h', 'e', 'c', 'b', 'a'])
  34. >>> d.extendleft(['i', 'j', 'k'])
  35. >>> d
  36. deque(['k', 'j', 'i', 'h', 'e', 'c', 'b', 'a'])
  37. # 想想挖掘机的履带,rotate 就不难理解了
  38. >>> d.rotate(1)
  39. >>> d
  40. deque(['a', 'k', 'j', 'i', 'h', 'e', 'c', 'b'])
  41. >>> d.rotate(2)
  42. >>> d
  43. deque(['c', 'b', 'a', 'k', 'j', 'i', 'h', 'e'])

defaultdict

defaultdict 对我来说最大的特点就是不会出现 KeyError 错误了,我们可以又回到列表元素统计那块来看看。

列表元素统计

普通实现

  1. >>> word_list = ["a", "b", "c", "c", "a", "a"]
  2. >>> cnt = {}
  3. >>> for word in word_list:
  4. ... if word not in cnt:
  5. ... cnt[word] = 1
  6. ... else:
  7. ... cnt[word] += 1
  8. ...
  9. >>> cnt
  10. {'a': 3, 'b': 1, 'c': 2}
  11. >>> cnt['d']
  12. Traceback (most recent call last):
  13. File "<stdin>", line 1, in <module>
  14. KeyError: 'd'

defaultdict 实现(没有用 if else 语句去判断哟)

  1. >>> from collections import defaultdict
  2. >>> word_list = ["a", "b", "c", "c", "a", "a"]
  3. >>> cnt = defaultdict(int)
  4. >>> for word in word_list:
  5. ... cnt[word] += 1
  6. ...
  7. >>> cnt
  8. defaultdict(<class 'int'>, {'a': 3, 'b': 1, 'c': 2})

OrderedDict

见闻知意,就是有顺序的字典,好像没啥特别好解释的了。关于 OrderedDict 的实际应用,csv.DictReader 有部分涉及。

  1. >>> from collections import OrderedDict
  2. >>> d = {"banana":3,"apple":2,"pear":1,"orange":4}
  3. >>> order_dict = OrderedDict(d)
  4. >>> order_dict
  5. OrderedDict([('banana', 3), ('apple', 2), ('pear', 1), ('orange', 4)])
  6. >>> order_dict.keys()
  7. odict_keys(['banana', 'apple', 'pear', 'orange'])
  8. >>> order_dict.values()
  9. odict_values([3, 2, 1, 4])
  10. >>> order_dict.items()
  11. odict_items([('banana', 3), ('apple', 2), ('pear', 1), ('orange', 4)])
  12. # 从后(前)删除元素
  13. >>> order_dict.popitem(last=True)
  14. ('orange', 4)
  15. >>> order_dict
  16. OrderedDict([('banana', 3), ('apple', 2), ('pear', 1)])
  17. >>> order_dict.popitem(last=False)
  18. ('banana', 3)
  19. >>> order_dict
  20. OrderedDict([('apple', 2), ('pear', 1)])
  21. # 移动元素到末尾
  22. >>> order_dict
  23. OrderedDict([('apple', 2), ('pear', 1), ('orange', 4)])
  24. >>> order_dict.move_to_end('apple')
  25. >>> order_dict
  26. OrderedDict([('pear', 1), ('orange', 4), ('apple', 2)])

namedtuple

命名元组,其实用数据库中数据表的思想理解比较容易一些:定义后的命名元组就相当于一个数据表,_fields 就相当于数据表的字段,实例化的对象就相当于生成了一条数据记录。

定义

  1. >>> from collections import namedtuple
  2. >>> User = namedtuple('User', ['name', 'age', 'id'])
  3. >>> User._fields
  4. ('name', 'age', 'id')
  5. >>> User = namedtuple('User', 'name age id')
  6. >>> User._fields
  7. ('name', 'age', 'id')

实例化

  1. >>> user = User('tester', '22', '12345678')
  2. >>> user
  3. User(name='tester', age='22', id='12345678')
  4. >>> user = User._make(['looking', 25, '12345678'])
  5. >>> user
  6. User(name='looking', age=25, id='12345678')

属性 

  1. >>> user = User._make(['looking', 25, '12345678'])
  2. >>> user.name
  3. 'looking'
  4. >>> user.age
  5. 25
  6. >>> user.id
  7. '12345678'

与字典的相互转换 

  1. >>> user._asdict()
  2. OrderedDict([('name', 'looking'), ('age', 25), ('id', '12345678')])
  3. >>> user._replace(age=22)
  4. User(name='looking', age=22, id='12345678')
  5. >>> dt = {'name':'looking', 'age':25, 'id':'12345678'}
  6. >>> User(**dt)
  7. User(name='looking', age=25, id='12345678')

与列表的相互转换 

  1. >>> user
  2. User(name='looking', age=25, id='12345678')
  3. >>> list(user)
  4. ['looking', 25, '12345678']
  5. >>> User._make(['looking', 25, '12345678'])
  6. User(name='looking', age=25, id='12345678')

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/860506
推荐阅读
相关标签
  

闽ICP备14008679号