6.组合数据类型
6.1 集合类型及操作
集合类型的定义
-
集合类型的定义
- 集合是多个元素的无序组合
- 集合类型与数学中的集合概念一致
- 集合元素之间无序,每个元素唯一,不存在相同元素
- python中集合元素不可更改,是不可变数据类型(这样不会出现更改后集合间突然出现相同元素的错误)
- 非可变数据类型有:整数、浮点数、复数、字符串类型、元组类型……
- 集合用大括号{}表示,元素间用逗号分隔
- 建立集合类型用{}或set(),其中{}为空时建立的是字典类型
- 建立空集合必须用set()
>>>A={“python”,123,(“python”,123)} #使用非空{}建立集合
{123,’python’,(‘python’,123)}
>>>B=set(“pypy123”) #使用set()建立集合注意区别它与{}对待字符串的不同;或者说set里面只能放一个数据,不能用逗号隔开
{‘1’,’p’,’2’,’3’,’y’}
>>>C={“python”,123,”python”,123}
{‘python’,123}
- 集合是多个元素的无序组合
-
重点
- 集合用大括号{}表示,元素间用逗号分隔
- 集合中每个元素唯一,不存在相同元素
- 集合元素之间无序
集合操作符
-
集合间操作
S T 并 S-T 差
S&T 交
S^T 补(S^T==(S T)-(S&T)) -
集合操作符
-
6个操作符
-
S T 返回一个新集合,包括在集合S和T中的所有元素
-
S-T
返回一个新集合,包括在集合S但不在T中的元素
-
S&T
返回一个新集合,包括同时在集合S和T中的元素
-
S^T
返回一个新集合,包括集合S和T中的非相同元素
-
S<=T或S<T
返回True/False,判断S和T的子集关系
-
S>=T或S>T
返回True/False,判断S和T的包含关系
-
-
4个增强操作符
-
S =T 更新集合S,包括在集合S和T中的所有元素
-
S-=T
更新集合S,包括在集合S但不在T中的元素
-
S&=T
更新集合S,包括同时在集合S和T中的元素
-
S^=T
更新集合S,包括集合S和T中的非相同元素
-
>>>A={“p”,”y”,123}
>>>B=set{“pypy123”}
>>>A-B
{123}
>>>B-A
{‘3’,’1’,’2’}
>>>A&B
{‘p’,’y’}
>>>A B {‘1’,’p’,’2’,’y’,’3’,123}
>>>A^B
{‘2’,123,’3’,’1’}
-
集合处理方法
-
集合处理方法
-
S.add(x)
如果x不在集合S中,将x增加到S
-
S.discard(x)
移除S中元素x,如果x不在集合S中,不报错
-
S.remove(x)
移除S中元素x,如果x不在集合S中,产生KeyError异常
-
S.clear()
移除S中所有元素
-
S.pop()
随机返回S的一个元素,并在S中移除它,若S为空产生KeyError异常
-
S.copy()
返回S的一个副本
-
len(S)
返回S的元素个数
-
x in S
判断S中是否有元素x,依此返回True/False
-
x not in S
判断S中是否有元素x,依此返回False/True
-
set(x)
将其他类型变量x转换为集合类型
>>>A={“p”,”y”,123}
>>> for item in A:
print(item,end=””)
p123y
用for in的方式遍历的顺序也许和你定义的顺序不同,但这个顺序在集合定义后就是固定的,只不过无法利用这个顺序
也可以用while循环遍历
>>>try:
while True:
print(A.pop(),end=””)
except:
pass
p123y
当然一般还是用for in方式遍历组合数据类型
-
集合类型应用场景
-
集合类型应用场景
-
包含关系比较
>>>“p” in {“p”,”y”,123}
True
>>>{“p”,”y”}>={“p”,”y”,123}
False
-
数据去重:集合类型所有元素无重复
>>>ls=[“p”,”p”,”y”,”y”,123]
>>>s=set(ls)#利用了集合无重复元素的特点
{‘p’,’y’,123}
>>>lt=list(s)#将集合转换为列表
[‘p’,’y’,123]
-
6.2 序列类型及操作
序列类型定义
- 序列是具有先后关系的一组元素
- 序列是一维元素向量,元素类型可以不同
- 类似数学元素序列:$s_0,s_1,…,s_{n-1}$
- 元素间由序号引导,通过下标访问序列的特定元素
- 序列是一个基类类型
- 序列类型的衍生有:字符串类型、元组类型、列表类型
- 序号的定义
- 正向递增序号
- 反向递减序号
序列处理函数及方法
-
序列类型通用操作符
-
6个操作符
-
x in s
如果x是序列s的元素,返回True,否则返回False
-
x not in s
与上面的相反
-
s+t
连接两个序列s和t
-
s*n或n*s
将序列s复制n次
-
s[i]
索引,返回s中的第i个元素,i是序列的序号
-
s[i:j]或s[i:j:k]
切片,返回序列s中第i到第j以k为步长的元素子序列
-
-
-
序列类型操作实例
>>>ls=[“python”,123,”.io”]
>>>ls[::-1]#列表取反
[‘.io’,123,’python’]
>>>s=”python123.io”
>>>s[::-1]#字符串取反(毕竟字符串类型也是序列类型的扩展形式)
‘oi.321nohtyp’
-
序列类型通用函数和方法
-
5个函数和方法
-
len(s)
返回序列s的长度
-
min(s)
返回序列s的最小元素,s中元素需要可比较(不可比较则报错)
-
max(s)
返回序列s的最大元素,s中元素需要可比较(不可比较则报错)
-
s.index(x)或s.index(x,i,j)
返回序列s从i开始到j位置中第一次出现元素x的位置(下标)
-
s.count(x)
返回序列s中出现x的总次数
-
-
-
序列类型操作实例
>>>ls=[“python”,123,”.io”]
>>>len(ls)
3
>>>s=”python123.io”
>>>max(s)#字符之间的比较按字母序比较
‘y’
元组类型及操作
-
元组类型定义
-
元组是序列类型的一种扩展
- 元组是一种序列类型,一旦创建就不能被修改
- 使用小括号()或tuple()创建,元素间用逗号分隔
- 可以使用或不使用小括号
如:
def func():
return 1,2
这里的1,2将默认处理为元组类型(1,2)
>>>creature=”cat”,”dog”,”tiger”,”human”
>>>creature
(‘cat’,’dog’,’tiger’,’human’)
>>>color=(0x001100,”blue”,creature)
(4352,’blue’,(‘cat’,’dog’,’tiger’,’human’))
-
-
元组类型操作
- 元组继承序列类型的全部通用操作
- 元组继承了序列类型的全部通用操作(操作符,处理函数,处理方法)
- 元组因为创建后不能修改,因此没有特殊操作
- 使用或不使用小括号
>>>creature=”cat”,”dog”,”tiger”,”human”
>>>creature[::-1]
(‘human’,’tiger’,’dog’,’cat’)
>>>color=(0x001100,”blue”,creature)
>>>color[-1][2]
‘tiger’
- 元组继承序列类型的全部通用操作
列表类型及操作
-
列表类型定义
- 列表是序列类型的一种扩展,十分常用
- 列表是一种序列类型,创建后可以随意被修改
- 使用方括号[]或list()创建,元素间用逗号分隔
- 列表中各元素类型可以不同,无长度限制
>>>ls=[“cat”,”dog”,”tiger”,1024]
>>>ls
[‘cat’,’dog’,’tiger’,1024]
>>>lt=ls
>>>lt
[‘cat’,’dog’,’tiger’,1024]
注意:方括号[]或list()真正创建一个列表,赋值仅传递引用(即lt,ls此时指向同一个列表,相当于重新命名)
- 列表是序列类型的一种扩展,十分常用
-
列表类型操作函数和方法
-
ls[i]=x
替换列表ls第i元素为x
-
ls[i:j:k]=lt
用列表lt替换ls切片后所对应元素子列表
-
del ls[i]
删除列表ls中第i元素
-
del ls[i:j:k]
删除列表ls中第i到第j以k为步长的元素
-
ls+=lt
更新列表ls,将列表lt中的元素加到列表ls后
-
ls*=n
更新列表ls,其元素重复n次
-
例子:
>>>ls=[“cat”,”dog”,”tiger”,1024]
>>>ls[1:2]=[1,2,3,4]
[‘cat’,1,2,3,4,’tiger’,1024]
>>>del ls[::3]
[1,2,4,’tiger’]
>>>ls*2
[1,2,4,’tiger’,1,2,4,’tiger’]
-
ls.append(x)
在列表ls最后增加元素x
-
ls.clear()
清空列表ls
-
ls.copy()
生成一个新列表,赋值ls中所有元素
-
ls.insert(i,x)
在列表ls的第i位置增加元素x
-
ls.pop(i)
将列表ls中第i位置元素取出并删除
-
ls.remove(x)
将列表ls中出现的第一个元素x删除
-
ls.reverse()
将列表ls中元素反转
-
例子:
>>>ls=[“cat”,”dog”,”tiger”,1024]
>>>ls.append(1234)
[‘cat’,’dog’,’tiger’,1024,1234]
>>>ls.insert(3,”human”)
[‘cat’,’dog’,’tiger’,’human’,1024,1234]
>>>ls.reverse()
[1234, 1024, ‘human’, ‘tiger’, ‘dog’, ‘cat’]
-
-
列表功能小测试
-
定义空列表lt
-
向lt新增5个元素
-
修改lt中第2个元素
-
向lt中第2个位置增加一个元素
-
从lt中第1个位置删除一个元素
-
删除lt中第1-3位置元素
-
判断lt中是否包含数字0
-
向lt新增数字0
-
返回数字0所在lt中的索引
-
lt的长度
-
lt中最大元素
-
清空lt
-
答案:
-
定义空列表lt
lt=[]
-
向lt新增5个元素
lt+=[1,2,3,4,5]
-
修改lt中第2个元素
lt[2]=6
-
向lt中第2个位置增加一个元素
lt.insert(2,7)
-
从lt中第1个位置删除一个元素
del lt[1]
-
删除lt中第1-3位置元素
del lt[1:4]
-
判断lt中是否包含数字0
0 in lt
-
向lt新增数字0
lt.append(0)
-
返回数字0所在lt中的索引
lt.index(0)
-
lt的长度
len(lt)
-
lt中最大元素
max(lt)
-
清空lt
lt.clear()
-
-
序列类型应用场景
-
序列类型应用场景
- 元组用于元素不改变的应用场景,更多用于固定搭配场景(如函数return)
- 列表更加灵活,它是最常用的序列类型
- 最主要作用:表示一组有序数据,进而操作它们
-
元素遍历
for item in ls:
<语句块>语句块>
for item in tp:#tp是元组类型变量
<语句块>语句块>
-
数据保护
-
如果不希望数据被程序改变,转换成元组类型
>>>ls=[“cat”,”dog”,”tiger”,1024]
>>>lt=tuple(ls)
>>>lt
(‘cat’,’dog’,’tiger’,1024)
-
主要是考虑到当一段程序是由多人完成时,存在不希望被修改的数据,可以要求程序之间的接口采用元组类型来传递
-
6.3 实例9:基本统计值计算
“基本统计值计算”问题分析
- 基本统计值
- 需求:给出一组数,对它们有个概要理解
- 该怎么做?
- 总个数、求和、平均值、方差、中位数…
- 总个数:len()
- 求和:for … in
- 平均值:求和/总个数
- 方差:各数据与平均数差的平方的和的平均数
- 中位数:排序,然后奇数找中间1个,偶数找中间2个取平均
“基本统计值计算”实例讲解
#CalStatisticsV1.py
def getNum():#获取用户不定长度的输入
nums=[]
iNumStr=input("请输入数字(回车退出):")
while iNumStr !="":
nums.append(eval(iNumStr))
iNumStr=input("请输入数字(回车退出):")
return nums
def mean(numbers):#计算平均值
s=0.0
for num in numbers:
s=s+num
return s/len(numbers)
def dev(numbers,mean):#计算方差
sdev=0.0
for num in numbers:
sdev+=(num-mean)**2
return pow(sdev/(len(numbers)-1),0.5)
def median(numbers):#计算中位数
sorted(numbers)#对列表进行排序#经个人查证,课程中这里应该讲错了,正确使用方法应为numbers=sorted(numbers)或numbers.sort()
size=len(numbers)
if size%2==0:
med=(numbers[size//2-1]+numbers[size//2])/2
else:
med=numbers[size//2]
return med
n=getNum()
m=mean(n)
print("平均值:{},方差:{:.2},中位数:{}".format(m,dev(n,m),median(n)))
“基本统计值计算”举一反三
- 技术能力扩展
- 获取多个数据:从控制台获取多个不确定数量数据的方法
- 分隔多个函数:模块化设计方法
- 充分利用函数:充分利用Python提供的内置函数
6.4 字典类型及操作
字典类型定义
-
理解“映射”
-
映射是一种键(索引)和值(数据)的对应
-
如:
内部颜色:蓝色
外部颜色:红色
“streetAddr”:”中关村南大街5号”
“city”:”北京市”
“zipcode”:”100081”
[“python”,123,”.io”]
的 0 1 2
即序列类型由0..N整数作为数据的默认索引
而映射类型则由用户为数据定义索引
-
-
字典类型是“映射”的体现
- 键值对:键是数据索引的扩展
- 字典是键值对的集合,键值对之间无序
- python采用大括号{}和dict()创建,键值对用冒号表示
- {<键1>:<值1>,<键2>:<值2>,...,<键n>:<值n>}值n>键n>值2>键2>值1>键1>
-
字典类型的用法
- 在字典变量中,通过键获得值
- <字典变量>={<键1>:<值1>,<键2>:<值2>,...,<键n>:<值n>} 值n>键n>值2>键2>值1>键1>字典变量>
- <值>=<字典变量>[<键>] 键>字典变量>值>
- <字典变量>[<键>]=<值> 值>键>字典变量>
- []用来向字典变量中索引或增加元素
>>>d={“中国”:”北京”,”美国”:”华盛顿”,”法国”:”巴黎”}
>>>d
{‘中国’: ‘北京’, ‘美国’: ‘华盛顿’, ‘法国’: ‘巴黎’}
>>>d[“中国”]
‘北京’
#如果要生成一个空的字典?
>>>de={};type(de)#type(x)用于检测变量x的类型
<class ‘dict’>
字典类型处理函数及方法
-
字典类型操作函数和方法
-
del d[k]
删除字典d中键k对应的数据值
-
k in d
判断键k是否在字典d中
-
d.keys()
返回字典d中所有的键信息
-
d.values()
返回字典d中所有的值信息
-
d.items()
返回字典d中所有的键值对信息
-
例子:
>>>d={“中国”:”北京”,”美国”:”华盛顿”,”法国”:”巴黎”}
>>>“中国” in d
True
>>>d.keys()
dict_keys([‘中国’, ‘美国’, ‘法国’])
>>>d.values()
dict_values([‘北京’, ‘华盛顿’, ‘巴黎’])
dict_keys,dict_values类型可以用for..in遍历,但不能当列表类型操作
-
d.get(k,<default>)
键k存在则返回相应值,不在则返回<default>值
-
d.pop(k,<default>)
键k存在则取出相应值,不在则返回<default>值
-
d.popitem()
随机从字典d中取出一个键值对,以元组形式返回
-
d.clear()
删除d所有键值对
-
len(d)
返回字典d中元素个数
-
例子:
>>>d={“中国”:”北京”,”美国”:”华盛顿”,”法国”:”巴黎”}
>>>d.get(“中国”,”伊斯兰堡”)
‘北京’
>>>d.get(“巴基斯坦”,”伊斯兰堡”)
‘伊斯兰堡’
>>>d.popitem()
(‘美国’, ‘华盛顿’)
-
-
字典功能小测试
-
定义空字典d
-
向d新增2个键值对元素
-
修改第2个元素
-
判断字符”c”是否是d的键
-
计算d的长度
-
清空d
-
答案:
-
定义空字典d
d={}
-
向d新增2个键值对元素
d[“a”]=1;d[“b”]=2
-
修改第2个元素
注意字典中的元素并没有顺序关系
d[“b”]=3
-
判断字符”c”是否是d的键
“c” in d
-
计算d的长度
len(d)
-
清空d
d.clear()
-
-
字典类型应用场景
-
映射的表达
- 映射无处不在,键值对无处不在
- 例如:统计数据出现的次数,数据是键,次数是值
- 最主要作用:表达键值对数据,进而操作它们
-
元素遍历
for k in d:#遍历字典d中的键
<语句块>语句块>
6.5 模块5:jieba库的使用
jieba库基本介绍
-
jieba库概述
- jieba库是优秀的中文分词第三方库
- 中文文本需要通过分词获得单个的词语
- jieba是优秀的中文分词第三方库,需要额外安装
- jieba库提供三种分词模式,而简单->只需掌握一个函数
-
jieba库的安装
cmd命令行:pip install jieba
-
jieba分词的原理
- jieba分词依靠中文词库
- 利用一个中文词库,确定汉字之间的关联概率
- 汉字间概率大的组成词组,形成分词结果
- 除了jieba自带的中文词库,用户还可以添加自定义词组(从而使其更适应某些具体领域的使用)
- jieba分词依靠中文词库
jieba库使用说明
-
jieba分词的三种模式
- 精确模式、全模式、搜索引擎模式
- 精确模式:把文本精确地切分开,不存在冗余单词
- 全模式:把文本中所有可能的词语都扫描出来,有冗余
- 搜索引擎模式:在精确模式基础上,对长词再次切分
- 精确模式、全模式、搜索引擎模式
-
jieba库常用函数
-
jieba.lcut(s)
精确模式,返回一个列表类型的分词结果
>>>jieba.lcut(“中国是一个伟大的国家”)
[‘中国’, ‘是’, ‘一个’, ‘伟大’, ‘的’, ‘国家’]
-
jieba.lcut(s,cut_all=True)
全模式,返回一个列表类型的分词结果,存在冗余
>>>jieba.lcut(“中国是一个伟大的国家”,cut_all=True)
[‘中国’, ‘国是’, ‘一个’, ‘伟大’, ‘的’, ‘国家’]
-
jieba.lcut_for_search(s)
搜索引擎模式,返回一个列表类型的分词结果,存在冗余
>>>jieba.lcut_for_search(“中华人民共和国是伟大的”)
[‘中华’, ‘华人’, ‘人民’, ‘共和’, ‘共和国’, ‘中华人民共和国’, ‘是’, ‘伟大’, ‘的’]
-
jieba.add_word(w)
向分词词典增加新词w
>>>jieba.add_word(“蟒蛇语言”)
-
6.6 实例10:文本词频统计
“文本词频统计”问题分析
“Hamlet英文词频统计”实例讲解
-
哈姆雷特(HAMLET)
初步思路:
- 获得一个HAMLET的英文文章,并将其中出现最多的单词输出
- 但是对于英文,我们会有一些单词表达方面的不同
- 单词大小写,逗号、冒号、叹号等
- 需要将文本进行噪音处理、归一化,才能在此基础上统计词频
#CalHamletV1.py
def getText():
txt=open("hamlet.txt","r").read()#打开hamlet.txt
txt=txt.lower()#将英文字母全转换为小写
for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘’{|}·~':
txt=txt.replace(ch," ")#将特殊字符替换为空格
return txt
hamletTxt=getText()
words=hamletTxt.split()
counts={}
for word in words:
counts[word]=counts.get(word,0)+1
items=list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
#列表类型的一种sort方法,其中的参数lambda用来指定在列表中使用哪一个多元选项的列作为排序列
#默认从小到大,reverse设为True就是从大到小
#它完成的工作就是对一个列表按照键值对的两个元素的第二个元素进行排序,排序方式是由大到小
for i in range(10):
word,count=items[i]
print("{0:<10}{1:>5}".format(word,count))
“《三国演义》人物出场统计”实例讲解
- 初步分析:
- 使用jieba库分词
- 不存在大小写
- 标点符号在分词后不用处理
#CalThreeKingdomsV1.py
import jieba
txt=open("threekingdoms.txt","r",encoding="utf-8").read()
words=jieba.lcut(txt)
counts={}
for word in words:
if len(word)==1:
continue
else:
counts[word]=counts.get(word,0)+1
items=list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(15):
word,count=items[i]
print("{0:<10}{1:>5}".format(word,count))
曹操 953
孔明 836
将军 772
却说 656
玄德 585
关公 510
丞相 491
二人 469
不可 440
荆州 425
玄德曰 390
孔明曰 390
不能 384
如此 378
张飞 358
- 但是这段代码仅能将中文进行分词并且进行词频统计,而离《三国演义》人物出场统计还有距离
- 将词频与人物相关联,面向问题:人物统计
- 修改:
- 排除词库
- 人物关联
#CalThreeKingdomsV2.py
import jieba
txt=open("threekingdoms.txt","r",encoding="utf-8").read()
excludes={"将军","却说","荆州","二人","不可","不能","如此"}
words=jieba.lcut(txt)
counts={}
for word in words:
if len(word)==1:
continue
elif word=="诸葛亮" or word=="孔明曰":
rword="孔明"
elif word=="关公" or word=="云长":
rword="关羽"
elif word=="玄德" or word=="玄德曰":
rword="刘备"
elif word=="孟德" or word=="丞相":
rword="曹操"
else:
rword=word
counts[rword]=counts.get(rword,0)+1
for word in excludes:
del counts[word]
items=list(counts.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(10):
word,count=items[i]
print("{0:<10}{1:>5}".format(word,count))
曹操 1451
孔明 1383
刘备 1252
关羽 784
张飞 358
商议 344
如何 338
主公 331
军士 317
吕布 300
可以继续将出现的其他非人物词汇加入排除词汇中,进行优化
-
《三国演义》人物出场TOP20
曹操、孔明、刘备、关羽、张飞、吕布、赵云、孙权、司马懿、周瑜、袁绍、马超、魏延、黄忠、姜维、马岱、庞德、孟获、刘表、夏侯惇
“文本词频统计”举一反三
- 举一反三
- 应用问题的扩展
- 《红楼梦》、《西游记》、《水浒传》…
- 政府工作报告、科研论文、新闻报道…
- 进一步呢?未来还有词云
- 应用问题的扩展
练习
-
实例9:基本统计值计算
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
获取以逗号分隔的多个数据输入(输入为一行),计算基本统计值(平均值、标准差、中位数)
除中位数外,其他输出保留小数点后两位。
请补充编程模板中代码完成
输入输出示例
输入 输出 示例 1 1,3,6,9,2,5,1
平均值:3.86,标准差:2.97,中位数:3
#请在...补充一行或多行代码 #CalStatisticsV1.py def getNum(): #获取用户不定长度的输入 ... def mean(numbers): #计算平均值 ... def dev(numbers, mean): #计算标准差 sdev = 0.0 for num in numbers: sdev = sdev + (num - mean)**2 return pow(sdev / (len(numbers)-1), 0.5) def median(numbers): #计算中位数 ... n = getNum() #主体函数 m = mean(n) print("平均值:{:.2f},标准差:{:.2f},中位数:{}".format(...)) --- #请在...补充一行或多行代码 #CalStatisticsV1.py def getNum(): #获取用户不定长度的输入 s=input() ls=list(eval(s)) return ls def mean(numbers): #计算平均值 tot=0.0 for num in numbers: tot+=num return tot/len(numbers) def dev(numbers, mean): #计算标准差 sdev = 0.0 for num in numbers: sdev = sdev + (num - mean)**2 return pow(sdev / (len(numbers)-1), 0.5) def median(numbers): #计算中位数 numbers.sort()#sorted(numbers) #print(numbers) if len(numbers)%2==0: return (numbers[len(numbers)//2-1]+numbers[len(numbers)//2])/2 else: return numbers[len(numbers)//2] n = getNum() #主体函数 m = mean(n) print("平均值:{:.2f},标准差:{:.2f},中位数:{}".format(m,dev(n,m),median(n))) --- #CalStatisticsV1.py def getNum(): #获取用户不定长度的输入 s = input() ls = list(eval(s)) return ls def mean(numbers): #计算平均值 s = 0.0 for num in numbers: s = s + num return s / len(numbers) def dev(numbers, mean): #计算标准差 sdev = 0.0 for num in numbers: sdev = sdev + (num - mean)**2 return pow(sdev / (len(numbers)-1), 0.5) def median(numbers): #计算中位数 numbers.sort() size = len(numbers) if size % 2 == 0: med = (numbers[size//2-1] + numbers[size//2])/2 else: med = numbers[size//2] return med n = getNum() #主体函数 m = mean(n) print("平均值:{:.2f},标准差:{:.2f},中位数:{}".format(m, dev(n,m),median(n))) 这是本课程的实例9: (1) 获取多个数据:从控制台获取逗号分隔的多个数据 (2) 多函数编写方法:模块化设计方法,每部分功能比较清晰 (3) 排序:列表ls的默认排序方法是ls.sort(),如果从大到小排序,用ls.sort(reverse=True)
-
实例10:文本词频统计 – Hamlet
描述
这是”实例”题,与课上讲解实例相同,请作答检验学习效果。
文本词频统计::一篇文章,出现了哪些词?哪些词出现的最多?
英文文本:hamlet.txt,参考附件(使用鼠标右键另存为下载)
请统计hamlet.txt文件中出现的英文单词情况,统计并输出出现最多的10个单词,注意:
(1) 单词不区分大小写,即单词的大小写或组合形式一样;
(2) 请在文本中剔除如下特殊符号:!”#$%&()*+,-./:;<=>?@[\]^_‘{ }~ (3) 输出10个单词,每个单词一行;
(4) 输出单词为小写形式。
输出样例
以下仅是输出样例(仅列出3个,需要列出10个),不是最终结果:
the
hamlet
be
#请在...处补充代码 def getText(): txt = open("hamlet.txt", "r").read() ... ... --- #请在...处补充代码 def getText(): txt = open("hamlet.txt", "r").read() txt=txt.lower() for item in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~': txt=txt.replace(item," ")#txt.replace(item," ") return txt txt=getText() words=txt.split() m={} for item in words: m[item]=m.get(item,0)+1 items=list(m.items()) items.sort(key=lambda x:x[1],reverse=True) for i in range(10): word,item=items[i] print(word) --- def getText(): txt = open("hamlet.txt", "r").read() txt = txt.lower() for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~': txt = txt.replace(ch, " ") #将文本中特殊字符替换为空格 return txt hamletTxt = getText() words = hamletTxt.split() counts = {} for word in words: counts[word] = counts.get(word,0) + 1 items = list(counts.items()) items.sort(key=lambda x:x[1], reverse=True) for i in range(10): word, count = items[i] # print ("{0:<10}{1:>5}".format(word, count)) 输出出现最多的10个单词和其出现次数 print (word) #输出出现最多的10个单词
-
人名独特性统计
描述
编程模板中给出了一个字符串,其中包含了含有重复的人名,请去重后给出独特性人名的统计。
输出模板中字符串共有多少个独特人名。
输入输出示例
这里是个示例,展示输出格式,不是结果。
输入 输出 示例 1 无 10
s = '''双儿 洪七公 赵敏 赵敏 逍遥子 鳌拜 殷天正 金轮法王 乔峰 杨过 洪七公 郭靖 杨逍 鳌拜 殷天正 段誉 杨逍 慕容复 阿紫 慕容复 郭芙 乔峰 令狐冲 郭芙 金轮法王 小龙女 杨过 慕容复 梅超风 李莫愁 洪七公 张无忌 梅超风 杨逍 鳌拜 岳不群 黄药师 黄蓉 段誉 金轮法王 忽必烈 忽必烈 张三丰 乔峰 乔峰 阿紫 乔峰 金轮法王 袁冠南 张无忌 郭襄 黄蓉 李莫愁 赵敏 赵敏 郭芙 张三丰 乔峰 赵敏 梅超风 双儿 鳌拜 陈家洛 袁冠南 郭芙 郭芙 杨逍 赵敏 金轮法王 忽必烈 慕容复 张三丰 杨逍 令狐冲 黄药师 袁冠南 杨逍 完颜洪烈 殷天正 李莫愁 阿紫 逍遥子 乔峰 逍遥子 完颜洪烈 郭芙 杨逍 张无忌 杨过 慕容复 逍遥子 虚竹 双儿 乔峰 郭芙 黄蓉 李莫愁 陈家洛 杨过 忽必烈 鳌拜 王语嫣 洪七公 韦小宝 阿朱 梅超风 段誉 岳灵珊 完颜洪烈 乔峰 段誉 杨过 杨过 慕容复 黄蓉 杨过 阿紫 杨逍 张三丰 张三丰 赵敏 张三丰 杨逍 黄蓉 金轮法王 郭襄 张三丰 令狐冲 郭芙 韦小宝 黄药师 阿紫 韦小宝 金轮法王 杨逍 令狐冲 阿紫 洪七公 袁冠南 双儿 郭靖 鳌拜 谢逊 阿紫 郭襄 梅超风 张无忌 段誉 忽必烈 完颜洪烈 双儿 逍遥子 谢逊 完颜洪烈 殷天正 金轮法王 张三丰 双儿 郭襄 阿朱 郭襄 双儿 李莫愁 郭襄 忽必烈 金轮法王 张无忌 鳌拜 忽必烈 郭襄 令狐冲 谢逊 梅超风 殷天正 段誉 袁冠南 张三丰 王语嫣 阿紫 谢逊 杨过 郭靖 黄蓉 双儿 灭绝师太 段誉 张无忌 陈家洛 黄蓉 鳌拜 黄药师 逍遥子 忽必烈 赵敏 逍遥子 完颜洪烈 金轮法王 双儿 鳌拜 洪七公 郭芙 郭襄''' ls=s.split() print(len(set(ls)))
-
字典翻转输出
描述
读入一个字典类型的字符串,反转其中键值对输出。
即,读入字典key:value模式,输出value:key模式。
输入格式
用户输入的字典格式的字符串,如果输入不正确,提示:输入错误。
输出格式
给定字典d,按照print(d)方式输出
输入输出示例
输入 输出 示例 1 {"a": 1, "b": 2}
{1: 'a', 2: 'b'}
try: d=eval(input()) dd={} for item in d.items(): a,b=item dd[b]=a print(dd) except: print("输入错误") --- s = input() try: d = eval(s) e = {} for k in d: e[d[k]] = k print(e) except: print("输入错误")
-
《沉默的羔羊》之最多单词
描述
附件是《沉默的羔羊》中文版内容,请读入内容,分词后输出长度大于2且最多的单词。
如果存在多个单词出现频率一致,请输出按照Unicode排序后最大的单词。
输入格式
文件
输出格式
字符串
输入输出示例
仅提供一个输出示范样例。
输入 输出 示例 1 无
羔羊
import jieba txt=open("沉默的羔羊.txt","r",encoding="utf-8").read() words=jieba.lcut(txt)#words=txt.lcut(txt) d={} for word in words: if len(word)<=2: continue else: d[word]=d.get(word,0)+1 #items=list(m) #items.sort(key=lambda x:x[1],reverse=True) #print(items[0]) maxcnt=0 maxuni="" for k in d: if maxcnt<d[k]: maxcnt=d[k] maxuni=k elif maxcnt==d[k] and (maxuni=="" or maxuni<k): maxcnt=d[k] maxuni=k print(maxuni) --- import jieba f = open("沉默的羔羊.txt") ls = jieba.lcut(f.read()) #ls = f.read().split() d = {} for w in ls: d[w] = d.get(w, 0) + 1 maxc = 0 maxw = "" for k in d: if d[k] > maxc and len(k) > 2: maxc = d[k] maxw = k if d[k] == maxc and len(k) > 2 and k > maxw: maxw = k print(maxw) f.close()
测验
单项选择题
-
列表ls,哪个选项对ls.append(x)的描述是正确的?
A .向列表ls最前面增加一个元素x
B. 向ls中增加元素,如果x是一个列表,则可以同时增加多个元素
C. 替换列表ls最后一个元素为x
D. 只能向列表ls最后增加一个元素x
D
ls.append(x),如果x是一个列表,则该列表作为一个元素增加的ls中。
-
序列s,哪个选项对s.index(x)的描述是正确的?
A. 返回序列s中元素x所有出现位置的序号
B. 返回序列s中x的长度
C. 返回序列s中序号为x的元素
D. 返回序列s中元素x第一次出现的序号
D
注意:s.index(x)返回第一次出现x的序号,并不返回全部序号。
-
以下不是Python序列类型的是:
A. 字符串类型
B. 元组类型
C. 列表类型
D. 数组类型
D
Python内置数据类型中没有数组类型。
-
给定字典d,哪个选项对d.values()的描述是正确的?
A. 返回一种dict_values类型,包括字典d中所有值
B. 返回一个元组类型,包括字典d中所有值
C. 返回一个列表类型,包括字典d中所有值
D. 返回一个集合类型,包括字典d中所有值
A
运行如下代码:(其中d是一个预定义的字典)
d={"a":1, "b":2} type(d.values())
输出结果是:<class ‘dict_values’>
d.values()返回的是dict_values类型,这个类型通常与for..in组合使用。
-
给定字典d,哪个选项对x in d的描述是正确的?
A. 判断x是否是字典d中的值
B. 判断x是否是字典d中的键
C. x是一个二元元组,判断x是否是字典d中的键值对
D. 判断x是否是在字典d中以键或值方式存在
B
键是值的序号,也是字典中值的索引方式。
因此,x in d 中的x被当作d中的序号进行判断。
-
关于Python组合数据类型,以下描述错误的是:
A. Python的字符串、元组和列表类型都属于序列类型
B. 组合数据类型可以分为3类:序列类型、集合类型和映射类型
C. 组合数据类型能够将多个相同类型或不同类型的数据组织起来,通过单一的表示使数据操作更有序、更容易
D. 序列类型是二维元素向量,元素之间存在先后关系,通过序号访问
D
序列类型总体上可以看成一维向量,如果其元素都是序列,则可被当作二维向量。
-
关于大括号{},以下描述正确的是:
A. 直接使用{}将生成一个元组类型
B. 直接使用{}将生成一个集合类型
C. 直接使用{}将生成一个字典类型
D. 直接使用{}将生成一个列表类型
C
集合类型和字典类型最外侧都用{}表示,不同在于,集合类型元素是普通元素,字典类型元素是键值对。
字典在程序设计中非常常用,因此,直接采用{}默认生成一个空字典。
-
关于Python的元组类型,以下选项错误的是:
A. 元组采用逗号和圆括号(可选)来表示
B. 一个元组可以作为另一个元组的元素,可以采用多级索引获取信息
C. 元组中元素必须是相同类型
D. 元组一旦创建就不能被修改
C
序列类型(元组、列表)中元素都可以是不同类型。
-
哪个选项是下面代码的输出结果?
d={'a':1,'b':2,'b':3}
A. 2
B. {‘b’:2}
C. 1
D. 3
D
创建字典时,如果相同键对应不同值,字典采用最后(最新)一个”键值对”。
-
S和T是两个集合,哪个选项对S^T的描述是正确的?
A. S和T的补运算,包括集合S和T中的非相同元素
B. S和T的差运算,包括在集合S但不在T中的元素
C. S和T的并运算,包括在集合S和T中的所有元素
D. S和T的交运算,包括同时在集合S和T中的元素
A
集合”交并差补”四种运算分别对应的运算符是:& - ^
程序设计题
-
**数字不同数之和 **
描述
获得用户输入的一个整数N,输出N中所出现不同数字的和。
例如:用户输入 123123123,其中所出现的不同数字为:1、2、3,这几个数字和为6。
输入输出示例
输入 输出 示例 1 123123123
6
s=str(input())#s=str(eval(input())) when input 0000001 wrong ls=[] for c in s: ls+=c lt=set(ls) ans=0 for i in lt: ans+=eval(i) print(ans) --- n = input() ss = set(n) s = 0 for i in ss: s += eval(i) print(s) 注意,字符串可以通过list()直接变成列表,或通过set()直接变成集合。
-
人名最多数统计
描述
编程模板中给出了一个字符串,其中包含了含有重复的人名,请直接输出出现最多的人名。
输入输出示例
这里是个示例,展示输出格式,不是结果。
输入 输出 示例 1 无 黄蓉
s = '''双儿 洪七公 赵敏 赵敏 逍遥子 鳌拜 殷天正 金轮法王 乔峰 杨过 洪七公 郭靖 杨逍 鳌拜 殷天正 段誉 杨逍 慕容复 阿紫 慕容复 郭芙 乔峰 令狐冲 郭芙 金轮法王 小龙女 杨过 慕容复 梅超风 李莫愁 洪七公 张无忌 梅超风 杨逍 鳌拜 岳不群 黄药师 黄蓉 段誉 金轮法王 忽必烈 忽必烈 张三丰 乔峰 乔峰 阿紫 乔峰 金轮法王 袁冠南 张无忌 郭襄 黄蓉 李莫愁 赵敏 赵敏 郭芙 张三丰 乔峰 赵敏 梅超风 双儿 鳌拜 陈家洛 袁冠南 郭芙 郭芙 杨逍 赵敏 金轮法王 忽必烈 慕容复 张三丰 赵敏 杨逍 令狐冲 黄药师 袁冠南 杨逍 完颜洪烈 殷天正 李莫愁 阿紫 逍遥子 乔峰 逍遥子 完颜洪烈 郭芙 杨逍 张无忌 杨过 慕容复 逍遥子 虚竹 双儿 乔峰 郭芙 黄蓉 李莫愁 陈家洛 杨过 忽必烈 鳌拜 王语嫣 洪七公 韦小宝 阿朱 梅超风 段誉 岳灵珊 完颜洪烈 乔峰 段誉 杨过 杨过 慕容复 黄蓉 杨过 阿紫 杨逍 张三丰 张三丰 赵敏 张三丰 杨逍 黄蓉 金轮法王 郭襄 张三丰 令狐冲 赵敏 郭芙 韦小宝 黄药师 阿紫 韦小宝 金轮法王 杨逍 令狐冲 阿紫 洪七公 袁冠南 双儿 郭靖 鳌拜 谢逊 阿紫 郭襄 梅超风 张无忌 段誉 忽必烈 完颜洪烈 双儿 逍遥子 谢逊 完颜洪烈 殷天正 金轮法王 张三丰 双儿 郭襄 阿朱 郭襄 双儿 李莫愁 郭襄 忽必烈 金轮法王 张无忌 鳌拜 忽必烈 郭襄 令狐冲 谢逊 梅超风 殷天正 段誉 袁冠南 张三丰 王语嫣 阿紫 谢逊 杨过 郭靖 黄蓉 双儿 灭绝师太 段誉 张无忌 陈家洛 黄蓉 鳌拜 黄药师 逍遥子 忽必烈 赵敏 逍遥子 完颜洪烈 金轮法王 双儿 鳌拜 洪七公 郭芙 郭襄 赵敏''' ls=s.split() d={} for item in ls: d[item]=d.get(item,0)+1 #lt=list(d.items()) #lt.sort(key=lambda x:x[1],reverse=True) #print(lt[0][0])#AC maxcnt=0 name="" for k in d: if d[k]>maxcnt: maxcnt=d[k] name=k print(name) --- s = '''双儿 洪七公 赵敏 赵敏 逍遥子 鳌拜 殷天正 金轮法王 乔峰 杨过 洪七公 郭靖 杨逍 鳌拜 殷天正 段誉 杨逍 慕容复 阿紫 慕容复 郭芙 乔峰 令狐冲 郭芙 金轮法王 小龙女 杨过 慕容复 梅超风 李莫愁 洪七公 张无忌 梅超风 杨逍 鳌拜 岳不群 黄药师 黄蓉 段誉 金轮法王 忽必烈 忽必烈 张三丰 乔峰 乔峰 阿紫 乔峰 金轮法王 袁冠南 张无忌 郭襄 黄蓉 李莫愁 赵敏 赵敏 郭芙 张三丰 乔峰 赵敏 梅超风 双儿 鳌拜 陈家洛 袁冠南 郭芙 郭芙 杨逍 赵敏 金轮法王 忽必烈 慕容复 张三丰 赵敏 杨逍 令狐冲 黄药师 袁冠南 杨逍 完颜洪烈 殷天正 李莫愁 阿紫 逍遥子 乔峰 逍遥子 完颜洪烈 郭芙 杨逍 张无忌 杨过 慕容复 逍遥子 虚竹 双儿 乔峰 郭芙 黄蓉 李莫愁 陈家洛 杨过 忽必烈 鳌拜 王语嫣 洪七公 韦小宝 阿朱 梅超风 段誉 岳灵珊 完颜洪烈 乔峰 段誉 杨过 杨过 慕容复 黄蓉 杨过 阿紫 杨逍 张三丰 张三丰 赵敏 张三丰 杨逍 黄蓉 金轮法王 郭襄 张三丰 令狐冲 赵敏 郭芙 韦小宝 黄药师 阿紫 韦小宝 金轮法王 杨逍 令狐冲 阿紫 洪七公 袁冠南 双儿 郭靖 鳌拜 谢逊 阿紫 郭襄 梅超风 张无忌 段誉 忽必烈 完颜洪烈 双儿 逍遥子 谢逊 完颜洪烈 殷天正 金轮法王 张三丰 双儿 郭襄 阿朱 郭襄 双儿 李莫愁 郭襄 忽必烈 金轮法王 张无忌 鳌拜 忽必烈 郭襄 令狐冲 谢逊 梅超风 殷天正 段誉 袁冠南 张三丰 王语嫣 阿紫 谢逊 杨过 郭靖 黄蓉 双儿 灭绝师太 段誉 张无忌 陈家洛 黄蓉 鳌拜 黄药师 逍遥子 忽必烈 赵敏 逍遥子 完颜洪烈 金轮法王 双儿 鳌拜 洪七公 郭芙 郭襄 赵敏''' ls = s.split() d = {} for i in ls: d[i] = d.get(i, 0) + 1 max_name, max_cnt = "", 0 for k in d: if d[k] > max_cnt: max_name, max_cnt = k, d[k] print(max_name) 这是传统解法,先使用字典建立"姓名与出现次数"的关系,然后找出现次数最多数对应的姓名。