Python 里面的 Collections 模块帮我们实现了很多常用的集合类,特别是一些字典累的子类,使用起来操作简单但却有着极强的作用,不像 Java 啥东西都要造轮子。之前遇到过一些字典类的灵活方法,打算根据Python官方文档,为 Counter, defaultdict, OrderedDict 三个常用的字典类进行一个总结。
defaultdict
defaultdict 可以指定字典的键所对应的值的类型,轻易地将键值对、字符串转换为字典、计数字典
1 指定值(字典的值的类型) 为列表
当键第一次出现的时候,字典对象 d 利用 default_factory 方法创建了一个空列表,然后 list.append 方法将其对应的值添加到空列表中;当键再次出现的时候,list.append() 方法再次将新的值添加进该键对应的列表。这个技术比用 dict.setdefault() 更方便和快捷。
1 s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] 2 3 d = defaultdict(list) 4 for k, v in s: 5 d[k].append(v) 6 print(d) 7 # {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}
用 setdefault 其实可以得到同样的效果,但是速度没有 defauldict 速度快,dict.setdefault(k, default) 作用是如果 k 在 dict 里面,则返回其 key;否则,将 k 与default 以键值对的形式添加到 dict 里面,并返回 default。是不是有点类似 Java 里 HashMap 的 getOrDefault(key, defaultValue) 方法,只不过这个方法是这样的:如果当前 map 存在 key,则返回 key 对应的 value,否则,返回默认值 defaultValue。
1 d = {} 2 for k, v in s: 3 d.setdefault(k, []).append(v) 4 d.items() 5 print(d) 6 # {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}
2 指定值为集合
1 s2 = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)] 2 d2 = defaultdict(set) 3 for k, v in s2: 4 d2[k].add(v) 5 print(d2) 6 # defaultdict(<class 'set'>, {'red': {1, 3}, 'blue': {2, 4}})
3 指定值为整形,用于计数
1 s3 = 'mississippi' 2 d3 = defaultdict(int) 3 for k in s3: 4 d3[k] += 1 5 print(d3) 6 # defaultdict(<class 'int'>, {'m': 1, 'i': 4, 's': 4, 'p': 2})
1 # dict.get(key, default = None) 2 # 参数: key,需要在字典中查找的值,若查找成功,则返回该键对应的值。 default: 如果查找不到该key则返回这个特定值 3 print(d3.get('dqwhui', None))
OrderedDict
是字典的一个子类(增: dic[key] = value; 删:dic.pop(key))
可以对键值对添加进字典的顺序进行记录: popitem(last = True) :LIFO模式, 删除最后进来的键值对; last = False : FIFO,删除最开始进来的键值对。
对已存在的健的位置进行操作: move_to_end(key, last = True),将已存在的健的位置移动到最右端,或者最左端(last = False)。
而且使用 OrderDict 可以很方便地实现LRU机制。
1 dic = OrderedDict() 2 dic['a'] = 1 3 dic['b'] = 2 4 dic['c'] = 3 5 6 for k,v in dic.items(): 7 print(k,v) 8 # a 1 9 # b 2 10 # c 3 11 12 dic.popitem(last = False) 13 for k,v in dic.items(): 14 print(k,v) 15 # b 2 16 # c 3 17 18 dic.move_to_end('b', last = True) 19 for k,v in dic.items(): 20 print(k,v) 21 # c 3 22 # b 2
Counter
Counter 是 dict 的一个子类,用于对哈希对象进行计数。他是一个以元素值作为键、元素出现的次数作为值的一个无序 collection。
1 对可迭代对象或者其他映射进行计数
1 # 1、1 2 s = 'sqwjodiqdjpneqonfpi23jpjp32pej3p' 3 dict1 = Counter(s) 4 print(dict1) 5 # Counter({'p': 6, 'j': 5, 'q': 3, '3': 3, 'o': 2, 'd': 2, 'i': 2, 'n': 2, 'e': 2, '2': 2, 's': 1, 'w': 1, 'f': 1}) 6 7 c = Counter(cats=4, dogs=8) 8 print(c) 9 # Counter({'dogs': 8, 'cats': 4}) 10 11 # 1、2 12 d = Counter(['eggs', 'ham']) 13 print(d, d['bacon']) 14 # Counter({'eggs': 1, 'ham': 1}) 0 15 16 d['eggs'] = 0 # counter entry with a zero count并不会将这个键值对消除 17 print(d) 18 # Counter({'ham': 1, 'eggs': 0}) 19 20 del d['eggs'] # 这样才会将键值对消除 21 print(d) 22 # Counter({'ham': 1})
2 新增的一些方法
1 # 2、1 elements() 2 c = Counter(a=4, b=2, c=0, d=-2) 3 print(list(c.elements())) 4 # ['a', 'a', 'a', 'a', 'b', 'b'] 5 6 # 2、2 most_common([n]) 返回一个列表,出现次数最多的前n个元素及其对应的次数,以元组形式 7 e = Counter('abracadabra').most_common(3) 8 print(e) 9 # [('a', 5), ('b', 2), ('r', 2)] 10 11 # 2、3 subtract([iterable-or-mapping]) 相当于做减法 12 c = Counter(a=4, b=2, c=0, d=-2) 13 d = Counter(a=1, b=2, c=3, d=-4, g = 8) 14 c.subtract(d) 15 print(c) 16 # Counter({'a': 3, 'd': 2, 'b': 0, 'c': -3, 'g': -8})
3 Counter 对象的常用形式
1 sum(c.values()) # total of all counts 2 c.clear() # reset all counts 3 list(c) # list unique elements 4 set(c) # convert to a set 5 dict(c) # convert to a regular dictionary 6 c.items() # convert to a list of (elem, cnt) pairs 7 Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs 8 c.most_common()[:-n-1:-1] # n least common elements 9 c += Counter() # remove zero and negative counts
1 d += Counter() 2 print(d) 3 # Counter({'g': 8, 'c': 3, 'b': 2, 'a': 1})
转载请注明出处~