1、如何快速找到多个字典的公共键
方法一
代码语言:javascript复制dl = [d1, d2, d3] # d1, d2, d3为字典,目标找到所有字典的公共键
[k for k in dl[0] if all(map(lambda d: k in d, dl[1:]))]
例
代码语言:javascript复制>>> dl = [{1:'life', 2: 'is'}, {1:'short', 3: 'i'}, {1: 'use', 4: 'python'}]
>>> [k for k in dl[0] if all(map(lambda d: k in d, dl[1:]))]
1
解析
代码语言:javascript复制# 列表表达式遍历dl中第一个字典中的键
>>> [k for k in dl[0]]
[1, 2]
# lambda 匿名函数判断字典中的键,即k值是否在其余字典中
>>> list(map(lambda d: 1 in d, dl[1:]))
[True, True]
>>> list(map(lambda d: 2 in d, dl[1:]))
[False, False]
# 列表表达式条件为上述结果([True, True])全为True,则输出对应的k值
1
方法二
代码语言:javascript复制# 利用集合(set)的交集操作
from functools import reduce
# reduce(lambda a, b: a*b, range(1,11)) # 10!
reduce(lambda a, b: a & b, map(dict.keys, dl))
reduce(function, sequence[, initial]) -> value 将包含两个参数的函数(
function
)累计应用于序列(sequence
)的项,从左到右,从而将序列reduce
至单个值。 例如,reduce(lambda x, y: x y,[1, 2, 3, 4, 5])
,则计算((((1 2) (3) 4) 5)
。如果存在initial
,则将其放在项目之前的序列,并作为默认值时序列是空的。
2、如何统计序列中元素的频度
方法一
代码语言:javascript复制sorted(((v, k) for k ,v in d.items()), reverse = True)[:3]
*sorted(iterable, /, , key=None, reverse=False) 返回一个新的列表,其中包含来自
iterable
的所有项目,并按升序排列。 可以提供自定义键函数来定制排序顺序和;反向标志(reverse
)可以设置为按降序请求结果。
上节提到匿名函数lambda作为内置函数的参数,其中有sorted函数 此时lambda函数用于指定对列表中所有元素进行排序的准则。
例如
sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))
将列表[1, 2, 3, 4, 5, 6, 7, 8, 9]
按照元素与5
距离从小到大进行排序,其结果是[5, 4, 6, 3, 7, 2, 8, 1, 9]
。
方法二
代码语言:javascript复制import heapq
heapq.nlargest(3, ((v, k) for k ,v in d.items()))
heapq.nlargest(n, iterable, key=None) 找出数据集中n个最大的元素。 相当于:
sorted(iterable, key=key, reverse=True)[:n]
方法三
代码语言:javascript复制from collections import Counter
c = Counter(data)
c.most_common(3)
Counter
代码语言:javascript复制# counter 生成counter
>>> from collections import Counter
>>> c = Counter() # 创建一个新的空counter
>>> c = Counter('abcasdf') # 一个迭代对象生成的counter
>>> c = Counter({'red': 4, 'yello': 2}) # 一个映射生成的counter
>>> c = Counter(cats=2, dogs=5) # 关键字参数生成的counter
>>> c = Counter('abcasd')
>>> c
Counter({'a': 2, 'c': 1, 'b': 1, 's': 1, 'd': 1})
>>> c2 = Counter(c)
>>> c2
Counter({'a': 2, 'c': 1, 'b': 1, 's': 1, 'd': 1})
Counter常用方法
elements()
按照counter的计数,重复返回元素
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
most_common(n)
按照counter的计数,按照降序,返回前n项组成的list; n忽略时返回全部
>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]
subtract([iterable-or-mapping])
counter按照相应的元素,计数相减
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
update([iterable-or-mapping])
不同于字典的update方法,这里更新counter时,相同的key的value值相加而不是覆盖
Counter 间的数学集合操作
代码语言:javascript复制>>> c = Counter(a=3, b=1, c=5)
>>> d = Counter(a=1, b=2, d=4)
>>> c d # counter相加, 相同的key的value相加
Counter({'c': 5, 'a': 4, 'd': 4, 'b': 3})
>>> c - d # counter相减, 相同的key的value相减,只保留正值的value
Counter({'c': 5, 'a': 2})
>>> c & d # 交集: 取两者都有的key,value取小的那一个
Counter({'a': 1, 'b': 1})
>>> c | d # 并集: 汇聚所有的key, key相同的情况下,取大的value
Counter({'c': 5, 'd': 4, 'a': 3, 'b': 2})
常见做法:
代码语言:javascript复制sum(c.values())
# 继承自字典的.values()方法返回values的列表,再求和
c.clear()
# 继承自字典的.clear()方法,清空counter
list(c)
# 返回key组成的list
set(c)
# 返回key组成的set
dict(c)
# 转化成字典
c.items()
# 转化成(元素,计数值)组成的列表
Counter(dict(list_of_pairs))
# 从(元素,计数值)组成的列表转化成Counter
c.most_common()[:-n-1:-1]
# 最小n个计数的(元素,计数值)组成的列表
c = Counter()
# 利用counter的相加来去除负值和0的值
3、如何让字典保持有序
代码语言:javascript复制>>> from collections import OrderedDict
# 不能使用自带的切片索引
>>> from itertools import islice
>>> players = ['a', 's', 'd', 'f']
>>> od = OrderedDict()
>>> for i, p in enumerate(players, 1):
... od[p] = i
od = {1: 'a', 2: 's', 3: 'd', 4: 'f'}
>>> def query_by_order(d, a,b=None):
... a -= 1
... if b is None:
... b = a 1
... return list(islice(od, a, b))
>>> query_by_order(od, 4)
['f']
4、如何实现用户历史记录功能
代码语言:javascript复制>>> from collections import deque # 双端队列
>>> q = deque([], 5)
# <-- [1,2,3,4,5] <--
>>> q.append(1)
>>> q.append(2)
>>> q.append(3)
>>> q.append(4)
>>> q.append(5)
# <-- [2,3,4,5,6] <--
>>> q.append(6)
# 将历史记录存到磁盘里去
>>> import pickle
>>> pickle.dump(q, open('save.pkl', 'wb')) # 第二个参数为文件对象
>>> pickle.load(open('save.pkl', 'rb'))
5、如何在列表、字典、集合中根据条件筛选数据
代码语言:javascript复制# filter函数
>>> filter(lambda x:x>=0, data)
# 列表表达式
>>> [x for x in data if x >= 0]
# 字典、集合表达式
>>> {k: v for k, v in d.iteritems() if v > 90}
>>> {x for x in s if x%3 == 0}