ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] # 数据结构 > 变量只能存储1个数据,存储大量数据的容器,在Python中称为:内置数据结构(Built-in Data Structure) 日常使用的网站,移动应用,甚至手机短信都依赖数据结构来进行存储数据,其中的数据以一种特定的格式存储在数据结构中,在用户需要时被拿出来展现. ![网络中数据](https://box.kancloud.cn/6b3e8de9843f5b26b9e1e1caadab0f5c_482x484.png) Python 有四种数据结构分别是:列表,字典,元组,集合. 每种数据结构都有自己的特点,并且有独到的用处,.整体上认识下四种数据结构 > 语法上: 列表中元素使用 `[]` 括起来, 字典和集合使用`{}` , 元组使用:`()` > 字典是中元素是成对的,格式key:value > set 保存的数据是唯一不重复的! > 列表最常用,是内存中一组连续的存储空间,和字符串类似! > 元组是数据不重复的列表 ## 列表(list) > 列表是内存中一组连续的存储空间. 列表的索引与字符串分片类似,同样是分正反两种索引方式,只要输入对应位置就能返回这个位置上的值: ![列表](https://box.kancloud.cn/cf7b6c6fff7baa6ab35033fe695b2344_567x127.png) ### 列表特点 1. 列表是内存中一组连续的存储空间, 2. 有序!索引值分正反两种索引, 从左到右第一个是0, 从右到左第一个是-1 3. 可存储任意类型数据 4. 列表是可修改的序列(每个值可被修改) 5. len(列表)获取长度 6. 不可通过索引新增数据 ### 创建和访问 > `变量名=[] ` #可先定义后赋值 > ` 变量名= [值1,值2,值3,.....]` #定义同时赋值 > `print(变量名[索引]);` > `del 列表变量[索引] ` 删除列表元素 ``` # 列表可存储任意类型数据 all_in_list =[ 1, #整数 1.0, #小数 'a word', #字符串 print(1), #函数 True, #布尔 [1,2], #列表套列表 (1,2), #元组 {'key':'value'} #字典 ] weekDay = ['周一','周二','周三','周四','周五','周六'] print(weekDay[0]) weekDay[0]='Monday' weekDay = ['周一','周二','周三','周四','周五','周六'] weekDay[6]='周末'; #错误 ``` ### 列表常用操作 > 根据索引找值, 修改,分片, 列表相加,列表相乘,额 成员检测,最大最小值,长度计算,求和 ``` nums1= [1,3,5,10]; nums2= [2,4,6]; print(nums1[0]) # 第一个 print(nums1[-1]) # 最后一个 print(len(nums1)) # 长度 nums1[0]=10; #修改 print(nums1+nums2) #相加 print(nums1*2) #相乘 print(nums1*2) #相乘 print(1 in nums1) #成员检测 print(len(nums1)) print('出现次数:',nums1.count(10)) print('和:',sum(nums1)) print('分片',nums1[:]) #分片,获取所有数据 print('分片',nums1[1:3]) #包头不包尾 print('分片',nums1[1:]) #开始位置到最后 print('分片',nums1[:3]) #结束位置之前,不包含结束位置 print('分片',nums1[0:3:1]) #开始到结束,不包含结束位置,并且获取数据时索引每次+跳步值来说获取,默认跳步值为1 ``` ### 列表相关方法 > Python内建函数/方法 | 序号 | 函数 | | --- | --- | | 1 | cmp(list1,list2) 比较两个列表元素 | | 2 | len(list) 比较两个列表元素 | | 3 | max(list) 最大值 | | 4 | min(list) 最小值 | | 5 | list(序列/seq) 将元组转换为列表 | > 列表自带方法(重点: 增加,修改,删除) | 序号 | 函数 | | --- | --- | | 1 | list.append(obj) 列表结尾增加新对象 | | 2 | list.count(obj) 统计列表中某个元素出现的次数 | | 3 | list.extend(seq) 列表尾部一次增加另一个序列的多个值 | | 4 | list.index(obj) 查找元素第一次的位置 | | 5 | list.insert(index,obj) 将对象插入列表 | | 6 | list.pop(obj=list[-1]) 移除一个元素(默认最后一个),并返回该元素值 | | 7 | list.remove(obj) 移除列表中某个值的第一个匹配项 | | 8 | liset.reserve() 反向列表元素 | | 9 | liset.sort([func]) 列表排序,可接收自定义的排序方法 | | 10 | copy(list) 复制原有列表 | ### 列表编列 > for...in 和 while 都可以循环编列列表 **for ** ``` for i in nums2: print('值',i) ``` **while** ``` i= 0 while i< len(nums2): print(nums2[i]) i +=1 ``` **列表嵌套循环** > 列表 = [[值1,值2], [值1,值2],.....] > 格式 fro 编列1,编列2 in ``` users = [['张三','20'],['李四','30']] for name,age in users: print(name+',年龄:'+age) ``` ### 练习 1. 控制台输入5个同学分数,计算平均分 2. 循环录入5个学员成绩,进行升序排列并输出 3. 有一个数列,8,4,1,23,344,12, 循环输出每个值,求所有数字和! 猜数游戏:从键盘中任意输入一个数字,判断数列是否包含在内 4. 从键盘输入5个同学语文的成绩,求考试最高分 5. 使用列表嵌套保存3个学员的名字,班级,和语文成绩!并循环展示 ## 元组(tuple) > > 元组是不可变的列表(稳固版的列表)!! 元组不具备修改功能! > (元组就是一种特殊格式列表而已, 列表是铅笔写的有序内容,元组就是钢笔写的有序内容) **创建** > 变量 = () 或变量=(值1,值2,值3,....) ``` weekday =('周一','周二','周三','周四') print(weekday.count('周一')) print(weekday.index('周二')) print(weekday[2]) ``` **特点** 1. 有序集合 2. 可以存储任意类型数据 3. 值不可变 **支持常用操作** > 索引,分片, 序列相加,序列相乘, 成员检测 **常用方法** >元组特有方法2个 ``` print(weekday.count('周一')) print(weekday.index('周二')) ``` > python内置操作方法 | 序号 | 函数 | | --- | --- | | 1 | cmp(list1,list2) 比较两个列表元素 | | 2 | len(list) 比较两个列表元素 | | 3 | max(list) 最大值 | | 4 | min(list) 最小值 | | 5 | tuple(序列/seq) 将元组转换为元组 | **编列方式for 或 while 和list相同** ``` i= 0 while i< len(weekday): print(weekday[i]) i +=1 ``` **多层编列** ``` for 变量1, 变量2 in 元组: 使用变量 ``` ## 字典(dict) >字典概念源于生活,专门用于存储生活中成对的数据,使用名字-内中的结构存储数据, 在Python中对应: >键(key) - 值(value) ,习惯上称为: "键值对" >没有顺序 ![dict](https://box.kancloud.cn/c5f15352664afa3e4f8d6395e8ecaa56_499x338.png) **特点** - 字典是无序序列,所以分片无法使用 - 字典中数必须以键值对存在 - 访问 ` 变量名[key]` - 键不能重复,值可重复 - key类型不可修改,value可为任意对象,可修改 ### 创建字典 ``` dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'} ``` 1. 空字典 ``` # `变量={} ` 或 `变量= dict()` zidian = {} zidian =dict() ``` 2. 有数据字典 ``` #变量= {键: 值, 键:值, 键:值,.....} url ={'百度':'baidu.com', 'QQ':'qq.com'' } #变量=dict({key:value,key:value,.....}) url =dict({'百度':'baidu.com', 'QQ':'qq.com'' }) #变量=dict(key=值,key=值) #变量=dict([{k:v},{k:v}......]) #变量=dict([(k:v),(k:v),(k:v),]) #变量=dict(zip((key1,key2,key3....),(value1,value2,value3......))) ``` ### 常用操作 > 访问,增加1个,增加多个,删除某个,判断是否存在 ``` url = {'baidu':'baidu.com','qq':'qq.com','ali':'ali.com'} print(url['baidu']) #访问 url['youku']= 'youku.com' #增加 del url['youku'] #删除 print('baidu' in url ) #检测数据是否在字典键中 ``` ### 遍历 1. 遍历建值 ``` #编列 for k,v in url.items(): print("名字:",k+"--值:"+v) ``` 2. 遍历键 ``` #编列 for k in url.keys(): print("名字:",k) ``` 3. 遍历值 ``` #编列 for v in url.values(): print("名字:",v) ``` ### 常用方法 > Python内置 | 序号 | 函数 | | --- | --- | | 1 | cmp(dict1,dict2) 比较两个字典元素 | | 2 | len(dict) 长度 | | 3 | max(dict) 最大值,默认比较key | | 4 | min(dict) 最小值,默认比较key | | 5 | str(dict) 转换为字符串输出 | | 6 | type(变量) 判断类型 | > 字典内置方法/函数 | 序号 | 函数 | | --- | --- | | 1 | 字典.clear() 清空 | | 2 | 字典.copy() 拷贝 | | 3 | 字典.formkeys() 创建新字典,键值都为key | | 4 | 字典.get(key,default=Node) 查找指定key的值,找不到返回默认值 | | 5 | 字典.set(key,default=Node) 和get类似,如果key不存在就设置为默认值 | | 6 | 字典.has_key(key) 是否包含key | | 7 | 字典.copy() 拷贝 | | 8 | 字典.item() 以列表返回每一项(键,值),实际上是一个元组 | | 9 | 字典.keys() 返回所有的键 | | 10 | 字典.values() 返回所有的值 | | 11 | 字典.update(字典/键值对) 一次更新多个字典 | | 12 | 字典.setdefault(key,值) 设置不存在的key的值 | #### 访问字典里的值 把相应的键放入熟悉的方括弧,如下实例: ``` dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}; print "dict['Name']: ", dict['Name']; print "dict['Age']: ", dict['Age']; 以上实例输出结果: dict['Name']: Zara dict['Age']: 7 ``` 如果用字典里没有的键访问数据,会输出错误如下: ``` dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}; print "dict['Alice']: ", dict['Alice']; 以上实例输出结果: dict['Zara']: Traceback (most recent call last): File "test.py", line 4, in <module> print "dict['Alice']: ", dict['Alice']; KeyError: 'Alice' ```` #### 修改字典 向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值对如下实例: ``` dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}; dict['Age'] = 8; # update existing entry dict['School'] = "DPS School"; # Add new entry print "dict['Age']: ", dict['Age']; print "dict['School']: ", dict['School']; 以上实例输出结果: dict['Age']: 8 dict['School']: DPS School ```` #### 删除字典元素 能删单一的元素也能清空字典,清空只需一项操作。 显示删除一个字典用del命令,如下实例: ``` dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}; del dict['Name']; # 删除键是'Name'的条目 dict.clear(); # 清空词典所有条目 del dict ; # 删除词典 print "dict['Age']: ", dict['Age']; print "dict['School']: ", dict['School']; ```` 但这会引发一个异常,因为用del后字典不再存在: ``` dict['Age']: Traceback (most recent call last): File "test.py", line 8, in <module> print "dict['Age']: ", dict['Age']; TypeError: 'type' object is unsubscriptable 注:del()方法后面也会讨论。 ```` 删除字典元素 字典键的特性 字典值可以没有限制地取任何python对象,既可以是标准的对象,也可以是用户定义的,但键不行。 两个重要的点需要记住: 1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住,如下实例: ``` dict = {'Name': 'Zara', 'Age': 7, 'Name': 'Manni'}; print "dict['Name']: ", dict['Name']; 以上实例输出结果: dict['Name']: Manni ``` 2)键必须不可变,所以可以用数,字符串或元组充当,所以用列表就不行,如下实例: ```` dict = {['Name']: 'Zara', 'Age': 7}; print "dict['Name']: ", dict['Name']; 以上实例输出结果: Traceback (most recent call last): File "test.py", line 3, in <module> dict = {['Name']: 'Zara', 'Age': 7}; TypeError: list objects are unhashable ```` ## 集合(Set) > 集合是高中数学中的概念! 保存一堆无序数据! 经常用于去掉重复数据. > 每个集合中元素都是无序的,不重复的任意对象. 我们可以通过集合判断从属关系,还可以通过集合把数据结构中重复的元素减掉 ![set](https://box.kancloud.cn/063b67f2cb52dec351d8a8e07e9f7c73_275x267.png) >集合不能被切片也不能别索引,除了做集合运算之外,集合元素也可以添加和删除 ``` a_set = {1,2,3,4} #创建 a_set = add(5); #增加 a_set.discard(5) #删除 ``` ### 定义和使用 ``` 变量 = set(); 变量 = {值1,值2,......} #注意集合内部元素是绝对唯一的,所以集合中多个相同数据只会保留一份! ``` ### 集合特点 1. 集合是一种无序数据类型,无法通过索引和分片进行操作 2. 集合内部元素是唯一的,经常用于去掉重复数据 ### 常用操作 **成员检测** ``` 数据 in/not in 集合 # 检测数据在集合中是否存在 ``` **编列** ```` 集合 = {值1,值2,值3....} for 变量 in 集合: 使用变量 ```` **带元组的集合遍历** ```` 集合 = {(值1,值2......),()}} for 变量1, 变量2 in 集合: 使用变量 ```` ### 常用函数 > Python内置 | 序号 | 函数 | | --- | --- | | 1 | len(set) 长度| | 2 | max(set) 最大值 | | 3 | min(set) 最小值 | | 4 | str(dict) 转换为字符串输出 | | 5 | set(seq) 其他序列变为集合 | > 集合内置方法:重点增加,删除 | 序号 | 函数 | | --- | --- | | 1 | 集合.add(数据) 增加 | | 2 | 集合.clear() 清空 | | 3 | 集合.copy() 拷贝 | | 4 | 集合.remove(值) 删除指定值,改变原有集合,如果要删的值不存在,报错| | 5 | 集合.discard(值) 移除指定值,改变原有集合,不存在不做任何操作 | | 5 | 集合.pop() 随机移除元素 | | 5 | 集合1.intersection(集合2) 交集 | | 5 | 集合1.difference(集合2) 差集 | | 5 | 集合1.dunion(集合2) 并集 | | 5 | 集合1.issubseet(集合2) 检测是否为子集返回布尔 | | 5 | 集合1.issuperset(集合2) 是否为超集 | | 5 | 集合1.difference_update(集合2) 无返回值, 差集,计算结果赋值给集合1 | | 5 | 集合1.intersection_update(集合2) 无返回值, 交集,计算结果赋值给集合1 | | 5 | 集合1.update(集合2) 无返回结果, 并集,计算结果赋值给集合1 | ### 冰冻集合/固定集合 frozenset >冰冻集合就是不可以进行任何修改相关操作的集合!, **创建** > `变量= frozenset()` > `变量= frozenset(一个序列)` 冰冻集合的操作相关函数和方法和普通集合一样! 只是不可以使用修改相关的方法. 注意: frozenset和普通集合一样无本质区别,能够使用的函数数量不一样.仅此而已 # 数据结构一些特点 > 常用的数据结构操作技巧,工作中需要熟悉,特此说明 1. `sorted(列表)`排序,按照长短,大小,英文字母顺序给每个元素排序.函数不会改变列表本身,可以理解为先将列表进行复制,然后进行排序. 2. `sorted(列表,reverse=True)` 逆向排序 ## 排序 ``` num_list = [6,4,6,1,2,67] print( sorted(num_list ) ) #排序 ``` ## 循环多个列表 >在整理列表时如果需要两个列表怎么办? 可以使用 zip 函数 ``` for a, b in zip(num, str): 使用变量 ``` ![多个列表](https://box.kancloud.cn/01bea51b55558463b3f92c22b6609fd1_537x147.png) ## 推导式/列表解析式 > 数据结构的推导式(List comprehension),另一个名字也叫"列表解析式", 使用方便,执行效率远远高于for循环 ``` #for 和推导式循环数据对比 #推导式 import time a =[] t0 = time.clock() for i in range(1,20000): a.append(i) print(time.clock()- t0,'s ') t0 = time.clock() b = [i for i in range(1,20000)] print(time.clock()-t0,'s') ``` 推导式用法: 可以简单看成两部分,红色虚线后面使我们数学的for循环表达式,虚线前面可以是我们想要放在列表中的元素,在这个案例中放在列表中的元素既是后面循环元素本身 ![推导式](https://box.kancloud.cn/1af6c43209b11cea162e19a8d0b6cd16_553x83.png) 更多案例 ``` a = [i**2 for i in range(1,10)] print(a) c = [j+1 for j in range(1,10)] k = [n for n in range(1,10) if n %2 ==0] z= [letter.lower() for letter in 'ABCDEFG'] #字典推导式略不同,因为字典结构k-v d= { i:i+1 for i in range(4)} e= {i:j for i,j in zip(range(1,6),'abcde')} f = {i:j.upper() for i,j in zip(range(1,6),'abcde')} ``` ## 循环时获取元素索引 > 列表是有序的,可以使用Python中 独有的函数 enumerate(枚举) 来进行 ``` letter = ['a','b','c','d','e'] for num, letter in enumerate(letter): print(letter ,'is',num) ``` # 项目:文章词频统计 文章词频统计 1. 标点符号不应该被统计 2. 单词不能被统计多次 3. python 大小写敏感,开头大写的不能单独统计 [文章下载](https://pan.baidu.com/s/1P6Fr4DAuyhyBUdS8QaRaZg) 密码:2tp3 ``` import string path = 'Walden.txt' #简单统计 with open(path, 'r',encoding='utf-8') as text: words = text.read().splite() for word in words: print('{}---{}次'.format(word,words.count(word))) #排重和符号 with open(path, 'r',encoding='utf-8') as text: words = [raw_word.strip(string.punctuation).lower() for raw_word in text.read().split()] words_index = set(words) counts_dict = {w:words.count(w) for w in words_index} for word in sorted(counts_dict,key=lambda x: counts_dict[x],reverse=True): print('{}----{} 次'.format(word, counts_dict[word])) ```