python基础二:python字典集合基础和一些经典使用案例 您所在的位置:网站首页 python的整除案例 python基础二:python字典集合基础和一些经典使用案例

python基础二:python字典集合基础和一些经典使用案例

2024-07-14 00:09| 来源: 网络整理| 查看: 265

1. 写在前面

借着昨天的列表, 今天整理一些python字典和集合的基础和一些经典使用案例, 依然是从使用的角度去整理, 关于列表的理论知识和细节知识, 这里不做整理。

首先, 会整理字典和集合的基本操作, 字典创建的五种方法, 涉及字典的基础操作(字典的遍历, 字典的键值集合获取, 判断某些键是否在字典中, 键值对的添加和删除), 然后整理学完了字典应该怎么去用, 这个就涉及了一些经典的使用案例(topn键, 重复最多, 逻辑合并等), 当然也是不全, 后期根据学习再进行补充。

大纲如下:

python字典和集合的基本操作经典使用案例 2. python字典和集合的基本操作 2.1 python字典

关于python字典的原理,这里就不多讲, 主要是怎么用? 首先是创建字典, 这里介绍五种常用的方法:

# 手动 dic = {'a': 1, 'b': 3, 'c': 3} # dict() dict(a=1, b=2, c=3) # 键值对+关键字参数 dict({'a':1, 'b': 2}, c=3, d=4) # 可迭代对象 dict([('a', 1), ('b', 2)], c=3) # fromkeys()方法 {}.fromkeys(['k1', 'k2', 'k3'], [1, 2, 3]) {'a':1}.fromkeys(['c', 'd'], [1, 2])

涉及字典的基本操作, 主要包括字典的遍历, 字典的键值集合获取, 判断某些键是否在字典中, 键值对的添加和删除等。

# 遍历 d = {'a':1, 'b':2, 'c':3} for key, value in d.items(): print(key, value) # 获得所有键的集合 set(d) set(d.keys()) # 获取值的集合 set(d.values()) # 判断键是否在字典中 if 'c' in d: print('yes') if 'e' not in d: print('no') # 添加修改键值对 d['d'] = 4 d # 删除键值对 del d['d'] d d.pop('c') d # 批量更新字典 update d.update({'c':3, 'd':4, 'e':5}) d # 如果仅当字典中不存在某个键值对时,才插入到字典中, 如果存在,不必插入 a = {'a': 1, 'b': 2} r = a.setdefault('c', 3) a

下面是三种字典视图:

"""字典视图 它们都是原字典的视图,修改原字典对象,视图对象的值也会发生改变。""" d = {'a': 1, 'b': 2, 'c': 3} d.values() d.keys() d.items()

关于字典, 我们要注意: 可哈希的对象才能作为字典的键。 这个详情看python幕后的不为人知(一)

2.2 python集合

集合是一种不允许元素出现重复的容器。如果判断一个列表中是否含有重复元素,便可借助集合这种数据类型。与字典(dict)类似,集合(set)也是由一对花括号({})创建。但是,容器内的元素不是键值对。同字典类似,集合内的元素必须是可哈希类型(hashable)。

"""集合创建""" a = {1, 2, 3} a = set([1, 3, 5, 7])

下面是关于集合的方法:

# 求并集 a = {1, 3, 5, 7} b, c = {3, 4, 5, 6}, {6, 7, 8, 9} d = a.union(b, c) print(d) # 求差集 m = a.difference(b, c) print(m) # 求交集 n = a.intersection(b, c) print(n) """是不是子集""" a = {1, 3, 5, 4} b = {1, 3, 5, 7} a.issubset(b)

上面这些都是一些常规操作,我们得掌握, 这些都是常规操作, 基于这些操作, 才能去完成一些复杂的任务。 下面的这些案例都会看到上面这些知识的身影。

3. 经典使用案例

字典并集 这个使用就是给定两个字典,然后返回字典的并集

def merge(d1, d2): return {**d1, **d2} a = {'a': 11, 'b': 12} b = {'a': 20, 'c': 30} merge(a, b) # 同键的会发生覆盖 ## 结果 {'a': 20, 'b': 12, 'c': 30}

求两个字典差 这个就是在说, 返回只出现在第一个字典里面的键值对, 也是传入两个字典

def difference(d1, d2): return dict([(k, v) for k, v in d1.items() if k not in d2]) a = {'a': 11, 'b': 12} b = {'a': 20, 'c': 30} difference(a, b) # {'b': 12}

按照字典的键值排序 这个就是给字典进行键值排序, 我们知道普通的字典是不管顺序的。 这里就是用sorted函数, 然后传入相应的比较值就可以。

def sort_by_key(d): return sorted(d.items(), key=lambda x: x[0]) def sort_by_values(d): return sorted(d.items(), key=lambda x: x[1]) # 可以指定reverse=True进行降序 m = dict([('c', 3), ('a', 2), ('b', 1)]) sort_by_key(m) # [('a', 2), ('b', 1), ('c', 3)] sort_by_values(m) # [('b', 1), ('a', 2), ('c', 3)]

这个地方比较难理解的就是函数里面的lambda那个地方, 上一篇文章中有个lambda的动画。 这里再结合这个例子,简单的说一下这个过程。因为这种lambda的形式,后面的案例还有很多次出现,所以最好弄明白内部的过程。 简单看一下内部的图: 在这里插入图片描述 上面这个图就是sort_by_key这个函数的工程过程, 当然这个是最后的结果了。 下面我说一下这个过程:

首先运行到sort_by_key这个函数, 传进来一个字典,用d指向它。 那么我们得想一下我们的目标是把字典按照键的大小进行排序, 那么肯定我们需要遍历字典中的每个键, 然后根据这个键的大小进行排序。 所以我们用了一个sorted函数, 第一个参数就是我们要排序的值, 传进去了d.items(), 这个就是[(a, 3), (b, 1), (c, 2)], 我们要把这个进行排序。 但是我们要按照什么样的规则排序呢? 得告诉sorted的函数, 这个就是key关键字, 让sorted函数根据这个关键字进行字典的排序。 但是key这里得是一个序列啊, 毕竟要排序嘛? 所以这里就用了一个lambda函数, 这里的x是lambda的形参, 它会依次指向字典里面的三个元组, 后面的x[0]表示lambda函数的返回值, 1就表示[a, b, c], 这样执行完lambda之后, key那里就是一个序列了, 然后sorted函数基于这个序列的值把字典进行排序返回。 按值排序其实同理, 无非就是把x[0]变成了x[1], 就是要按照序列[3, 1, 2]将字典进行排序返回。

所以key 函数一般会与 lambda 匿名函数结合使用, 而这个原理就是上面的这个过程, 有种遍历获得可迭代对象的每个元素,然后进行操作的感觉。 包括之前的max(lst, key=lambda v: lst.count(v))求列表里面出现次数最多的元素, 根据上面的这个过程,这里就一目了然了。 key这里就是每个元素出现的次数, max会求出最大次数, 然后返回lst里面对应的元素。好吧, 最后面我会拿上一次的列表例子详细说一下这个过程。

最大键或者最大值 这个就是返回字典里面有最大键的那个键值对。或者是有最大值的键值对。 最大键的思路就是用max函数获取最大键, 然后根据最大键返回相应的值。

def max_key(d): if len(d) == 0: return [] max_key = max(d.keys()) return (max_key, d[max_key]) max_key({'a': 3, 'b': 2, 'c': 1}) # ('c', 1)

最大值的思路也是求出最大值, 然后遍历字典, 看看哪个键值对等于这个值, 返回。

def max_values(d): if len(d) == 0: return [] max_values = max(d.values()) return [(key, max_values) for key in d if d[key]==max_values] max_values({'a': 3, 'b': 2, 'c': 1}) # [('a', 3)]

集合最值 这个是找出集合里面的最大值和最小值, 并装到元组里面返回。

def set_max_min(s): return (max(s), min(s)) set_max_min({5, 1, 2, 4}) # (5, 1)

更长的集合 这个就是传入多个集合, 返回最长的那个, 和上一次的列表最长差不多

def long(*s): return max(*s, key=lambda x : len(x)) long({1,3,5,7},{1,5,7})

重复最多 这个就是在两个列表中, 找出重叠次数最多的元素进行返回。 这个得先一下思路: 这个问题我是有两个列表, 然后返回重叠次数最多的元素。也就是在两个列表中都出现, 且出现的次数最多。 所以分为下面三个步骤:

首先, 我得先把在两个列表中都出现的元素找出来。 这个就用到了集合和交操作其次, 我得获得上面每个元素在两个列表中出现的次数, 然后返回最小的次数作为每个元素的出现次数最后, 在这些次数中, 找到最大次数对应的元素

基于上面的分析, 我们就可以写一个函数了:

def overlap_max(lst1, lst2): # 首先, 获得交集 overlap = set(lst1).intersection(set(lst2)) # 遍历这个overlap, 看看在两个列表中的出现次数, 返回最小值 ox = [(x, min(lst1.count(x), lst2.count(x))) for x in overlap] # 返回这里面的最大次数的元素 return max(ox, key=lambda x: x[1]) max_overlap([1,2,2,2,3,3],[2,2,3,2,2,3]) # (2, 3)

topn键 这个是找字典前n个最大值,对应的键。 这个我们的常规思路就是先把字典的值进行排序, 然后返回前n个最大的。 所以就来了第一版:

def topn_dict(d, n): if len(d) == 0: return sort_val_d = sorted(d.items(), key=lambda x: x[1]) return [ele[0] for ele in sort_val_d[:n]] topn_dict({'a': 10, 'b': 8, 'c': 9, 'd': 10}, 3) # ['a', 'd', 'c']

当然, python还有一个简洁版, 那就是用heapq里面的nlargest函数。这个参数,接收的第一个参数就是n, 其次是对象, 然后是key, 最后返回的是前n个最大的。 其实内部原理就是我上面的那种。 但既然有了, 我们就可以直接用。

from heapq import nlargest def topn_dict1(d, n): return nlargest(n, d, key=lambda k: d[k])

一键对多值字典 当有一个键对应多个值的时候,我们如何存到字典中? 看下面例子:

lst = [(1, 'apple'), (2, 'orange'), (1, 'compute')] dict(lst) # {1: 'compute', 2: 'orange'}

lst有是元组的列表, 如果想把这个存成字典的形式, 使用dict之后,变成了{1: 'compute', 2: 'orange'}, 也就是1键对应了两个值, 用dict,变成字典忽略了一个。 所以想办法自己存:直观思路就是遍历列表, 如果这个键在字典中, 那么直接对应的k加入元素, 否则,就建一个k加入元素。 所以出来了第一个版本:

d = {} for k, v in lst: if k not in d: d[k] = [] d[k].append(v) d # {1: ['apple', 'compute'], 2: ['orange']}

这样就可以了, 但是有一个if判断,不是很优雅, 所以可以使用collections模块中的defaultdict, 它能创建属于某个类型的自带初始值的字典

from collections import defaultdict d = defaultdict(list) for k, v in lst: d[k].append(v) d # defaultdict(list, {1: ['apple', 'compute'], 2: ['orange']})

逻辑上合并字典 这个是在逻辑上合并字典, 不重新生成字典, 改变新的字典的值原字典也会改变。 我们上面也有个合并字典, 我们拿下来看一下普通的字典合并:

def merged(d1, d2): return {**d1, **d2} dic1 = {'x': 1, 'y': 2 } dic2 = {'y': 3, 'z': 4 } merged_dic = merged(dic1, dic2) merged_dic # {'x': 1, 'y': 3, 'z': 4} merged_dic['x'] = 10 merged_dic # {'x': 10, 'y': 3, 'z': 4} dic1 # {'x': 1, 'y': 2}

这个我们会发现, 如果是改变新的字典merged_dict的值, 发现不影响dic1。 那么有没有一种方法, 合并后的字典不重新建立字典呢? 只从逻辑上合并, 如果改了新字典中的值,能够使得原来字典的值也相应变化呢? 那就是collections模块里面的ChainMap函数了。 它在内部创建了一个容纳这些字典的列表。使用 ChainMap 合并字典, 可以实现字典逻辑上的合并。

from collections import ChainMap mer = ChainMap(dic1, dic2) mer # ChainMap({'x': 1, 'y': 2}, {'y': 3, 'z': 4}) mer['x'] = 10 mer # ChainMap({'x': 10, 'y': 2}, {'y': 3, 'z': 4}) dic1 # {'x': 10, 'y': 2}

可以发现, 这个就实现了字典的逻辑合并。

上面就是python字典的基础和经典使用案例了。

下面借着这个机会再补充一个例子, 因为上面的某些案例中用到了key函数与lambda进行结合。 我们看看究竟内部这个函数在怎么样工作: 看一个返回最长列表的例子(和上面最大长度的集合的例子一样):

def max_len(*lists): return max(*lists, key=lambda v: len(v)) r = max_len([1, 2, 3], [4, 5, 6, 7], [8]) r # [4, 5, 6, 7]

在这里详细说一下lambda函数。

首先, 把下面的三个列表传入到max_len函数中, 内部是这样的: 在这里插入图片描述 max_len 函数被传入三个实参,类型为 list,如上图所示,lists 变量指向最下面的 tuple 实例。

接着往下运行, 就会出现lambda函数, 它的父函数是是f1, 也就是max_len函数。 那么这里的lambda函数里面, v到底是啥? lambda的返回值又是啥?

我们看看这个v: 在这里插入图片描述 非常容易看出, v 指向 tuple 实例的第一个元素,指向的线和箭头能非常直观地反映出来。 那么v就是[1, 2, 3], 而len(v) 就是3, 这个就是lambda函数的返回值。 在这里插入图片描述 然后, v指向元组中的下一个元素, 返回值是4 在这里插入图片描述 然后,v 指向 tuple 的最后一个元素 [8],返回值为 1。 在这里插入图片描述 根据key确定的比较标准, max函数的返回值为红色字体指向的元素, 也就是返回[4, 5, 6, 7] 在这里插入图片描述 这其实就是lambda函数背后起的作用。 包括上面的sorted里面的lambda, max里面的lambda, 他们都是起的类似的作用。下面是完整的动画演示: 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有