Python 实用小技巧(2)

2021-06-24 10:04:54 浏览数 (1)

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的计数,重复返回元素

代码语言:javascript复制
>>> 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忽略时返回全部

代码语言:javascript复制
>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]

subtract([iterable-or-mapping]) counter按照相应的元素,计数相减

代码语言:javascript复制
>>> 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}

0 人点赞