Python数据结构与算法

蔚落 2022-05-15 03:17 311阅读 0赞

Python数据结构与算法

一、筛选数据

0x1 列表

列表解析

  1. [x for x in data if x>= 0]

filter函数:

  1. g = filter(lambda x : x >=0, data)
  2. python3中,得到的是构造器,要用list才可以得到结果
  3. list(g)

0x2 字典

字典解析

  1. {k:v for k, v in d.items() if v> 90}
  2. d = {
  3. 'student%d' %i :randint(50,100) for i in range(1,21)}
  4. {k:v for k,v in d.items() if v>=90}

0x3 集合

集合解析

  1. {x for x in s if x%3==0}

二、元组命名

student = (‘mubai’,20,’male’,’1948877055@qq.com’)
访问里面的数据用下标索引,可读性不好。

方案1:定义一系列数值常量或枚举类型

  1. NAME,AGE,SEX,EMAIL = range(4)
  2. student[NAME] //mubai

方案2:使用标准库中collections.namedtuple替代内置tuple

  1. //使用枚举
  2. from enum import IntEnum
  3. class StudentEnum(IntEnum):
  4. NAME = 0
  5. AGE = 1
  6. SEX = 2
  7. EMAIL = 3
  8. student[StudentEnum.AGE] = 20
  9. //使用collections.namedtuple
  10. from collections import namedtuple
  11. Student = namedtuple('Student',['name','age','sex','email'])
  12. s = Student('mubai',20,'male','1948877055@qq.com')
  13. //s.name = mubai

三、字典排序

根据成绩高低排名:
{ 'LiLei':79, 'Jim':88, 'Lucy':92, ... }

将字典中的各项转换为元组,使用内置函数sorted排序。

方案一:将字典中的项转化为(值,键)元组。(列表解析或zip )

  1. //随机生成成绩表
  2. from random import randint
  3. g = {k: randint(60,100) for k in 'abcdefgh'}
  4. //列表解析
  5. d = [(v,k) for k,v in g.items()]
  6. //zip函数
  7. d = list(zip(g.values(),g.keys())
  8. m = sorted(d,reverse=True)

方案二:传递sorted函数的key参数

  1. m = sorted(g.items(),key=lambda item:item[1],reverse=True)

最终排名:

  1. n = list(enumerate(m,1)) //对m进行排序,加序号
  2. for i,(k,v) in n: //迭代n,增加排序
  3. g[k] = (i,v) //{
  4. 'a': (1, 100), 'b': (7, 66), 'c': (8, 65), ...}
  5. o = {k:(i,v) for i,(k,v) in enumerate(m,1)}

四、统计频度

某随机序列找到出现次数最高的3个元素,它们出现次数是多少?

方案一:将序列转换为字典{元素:频度},根据字典中的值排序。

  1. data = [randint(0,20) for _ in range(30)]
  2. //新建一个字典,值全为0
  3. d = dict.fromkeys(data,0)
  4. //迭代,值加一
  5. for x in data:
  6. d[x] += 1
  7. m = sorted([(v,k) for k,v in d.items()],reverse=True)
  8. sorted(((v,k) for k,v in d.items()),reverse=True)[:3] //生成器解析 取前三个
  9. //不用sorted全部计算,采用堆
  10. import heapq
  11. m = heapq.nlargest(3,((v,k) for k,v in d.items()))

方案二:使用标准库collections中的Counter对象。

  1. from collections import Counter
  2. c = Counter(data) //统计词频
  3. c.most_common(3) //选前三

统计文本文件词频:

  1. from collections import Counter
  2. text = open('a.txt').read()
  3. import re //正则表达式
  4. word_list = re.split('\W+',txt) //非字符切割文本
  5. t = Counter(word_list)
  6. t.most_common(10)

五、字典中的公共键

场景:指定球员多场球赛进球数。
模拟:随机生成多个字典,找出公共建。

  1. from random import randint,sample
  2. d = sample('abcdefgh',randint(3,6)) #进球的球员
  3. d1 = {k:randint(1,4) for k in d}
  4. d2 = {k:randint(1,4) for k in d}
  5. d3 = {k:randint(1,4) for k in d}
  6. dl = [d1,d2,d3]

方案一、迭代每个字典的键

  1. //循环迭代
  2. for k in d1:
  3. if k in d2 and k in d3:
  4. print(k)
  5. //列表解析
  6. [k for k in d1 if k in d2 and k in d3]
  7. [k for k in dl[0] if all(map(lambda d:k in d, dl[1:]))]

方案二、利用集合(set)的交集操作

Step1:使用字典的keys()方法,得到一个字典keys的集合.
Step2:使用map函数,得到每个字典keys的集合.
Step3:使用reduce函数,取所有字典的keys集合的交集.

  1. # reduce()函数介绍
  2. //10的阶乘
  3. from functools import reduce
  4. reduce(lambda a,b : a*b,range(1,11))
  5. d1 = {k:randint(1,4) for k in d}
  6. d2 = {k:randint(1,4) for k in d}
  7. d3 = {k:randint(1,4) for k in d}
  8. d1&d3&d2
  9. //下面是最终结果
  10. reduce(lambda a,b:a&b,map(dict.keys,dl))

五、让字典有序

Python3.5之前的字典不是有序的,存和取位置并不是对应好的。
案例:编写根据排名获取选手的函数接口

方案:使用标准库collections中的OrderedDict

  1. from collections import OrderedDict
  2. players = list('abcdefgh')
  3. from random import shuffle #洗牌函数
  4. shuffle(players)
  5. od = OrderedDict()
  6. for i,p in enumerate(players,1):
  7. od[p] = i
  8. #根据名字查询成绩
  9. def query_by_name(d,name):
  10. return d[name]
  11. from itertools import islice
  12. def query_by_order(d,a,b=null):
  13. a -= 1
  14. if b is None:
  15. b = a + 1
  16. return list(islice(od,a,b))
  17. query_by_order(od,3)
  18. query_by_order(od,3,6)

六、历史记录存储

案例:现在我们制作了一个简单的猜数字的小游戏,如何添加历史记录功能,显示用户最近猜过的数字?

方案一:使用容量为n的队列存储历史记录

使用标准库collections中的deque,它是一个双端循环队列

  1. from collections import deque
  2. q = deque([],5) //[]初始化 队列长度
  3. q.append(1) //入队
  4. q.appendleft(2) //从左入队
  5. q.pop(1) //出队

方案二:使用pickle模块将历史记录存储到硬盘,以便下次启动使用

pickle.dump(obj, file, [,protocol])
注解:将对象obj保存到文件file中去。

  1. import pickle
  2. pickle.dump(q.open('save.pkl','wb')) #以二进制方式写入
  3. p = pickle.load(open('save.pkl','rb')) #以二进制方式读取

发表评论

表情:
评论列表 (有 0 条评论,311人围观)

还没有评论,来说两句吧...

相关阅读