python(北京理工大学慕课)6-7章

6.组合数据类型

6.1 集合类型及操作 

6.1.1集合类型定义 

集合是多个元素的无序组合

1)集合类型与数学中的集合概念一致

2)集合元素之间无序,每个元素唯一,不存在相同元素 

3)集合元素不可更改,不能是可变数据类型(数值类型【int、float、bool】、字符串类型、元组)

4)集合用大括号 {} 表示,元素间用逗号分隔

5)建立集合类型用 {} 或 set() 

6)建立空集合类型,必须使用set() 【{}这个符号用来建立字典类型】

6.1.1补充:可变数据类型和不可变数据类型

  • 可变数据类型:当该数据类型对应的变量的值发生了变化时,如果它对应的内存地址不发生改变,那么这个数据类型就是 可变数据类型。【引用数据类型】

               list(列表)、dict(字典)、set(集合,不常用)

  • 不可变数据类型:当该数据类型对应的变量的值发生了变化时,如果它对应的内存地址发生了改变,那么这个数据类型就是 不可变数据类型。【数据值类型】

          数值类型(int、float、bool)、string(字符串)、tuple(元组)

案例:

>>> A = {"python", 123, ("python",123)} #使用{}建立集合
        {123, 'python', ('python', 123)}

>>> B = set("pypy123") #使用set()建立集合
        {'1', 'p', '2', '3', 'y'}

>>> C = {"python", 123, "python",123}
        {'python', 123} 

 

 

6.1.2集合操作符 

 

  • 六个操作符

 

 

  • 四个增强操作符 【更新就是覆盖了原来的值,不是追加在原来值后面】

 

 案例:

>>> 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'}

 

6.1.3集合处理方法 

 

 

 

案例:

#集合遍历
 A = {"p", "y" , 123} 
 for item in A:
      print(item, end="")

#输出结果:p123y ,可以看出集合无序

#try - except可捕捉异常

 try:
    while True:
        print(A.pop(), end=""))
except: 
    pass    
#输出结果:p123y ,可以看出集合无序

 

 

6.1.4集合类型应用场景

1)包含关系比较

"p" in {"p, "y" , 123}
输出:True


{"p", "y"} >= {"p", "y" , 123}
输出:False

2)数据去重:集合类型所有元素无重复

ls = ["p , "p", "y", "y", 123]
s = set(ls) # 利用了集合无重复元素的特点,强转set()
{'p', 'y', 123}


lt = list(s) # 还可以将集合转换为列表
['p', 'y', 123]

 

 

6.2 序列类型及操作 

6.2.1序列类型定义

  • 序列是具有先后关系的一组元素

  1)序列是一维元素向量,元素类型可以不同

  2)类似数学元素序列: s0, s1, … , sn-1

  3)元素间由序号引导,通过下标访问序列的特定元素

 

  • 序列是一个基类类型 【序列的一些特性,操作方法,对于序列的派生类型也适用,但是下面的派生类型也有自己定义的操作方法】

 

 

  • 序号的定义

 

 

 

6.2.2序列处理函数及方法

  • 六个操作符

 

 案例:

ls = ["python", 123,".io"] 
ls[::-1]
#输出结果:['.io', 123, 'python']

s = "python123.io"
s[::-1]
#输出结果:'oi.321nohtyp'

#字符串也具有序列类型的操作

 

  • 5个函数和方法

 

 

案例:

ls = ["python", 123, ".io"] 
len(ls)
#结果:3

s = "python123.io"
max(s)
#结果:'y'

 

 

 

6.2.3元组类型及操作

1)定义:元组是序列类型的一种扩展

1.元组是一种序列类型,一旦创建就不能被修改

2.使用小括号 () 或 tuple() 创建,元素间用逗号 , 分隔 

3.可以使用或不使用小括号 【比如函数返回多个值时 语句“return 1,2”,默认返回值就是一个元组类型】

4. 元组继承了序列类型的全部通用操作

5.元组因为创建后不能修改,因此没有特殊操作

6.使用或不使用小括号

案例:

creature = "cat", "dog","tiger","human"
creature 
#结果:('cat', 'dog', 'tiger', 'human')

color = (0x001100, "blue", creature)
color
#结果:(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'

 

 

6.2.4列表类型及操作

1. 列表类型定义

列表是序列类型的一种扩展,十分常用,列表是引用类型

1)列表是一种序列类型,创建后可以随意被修改

2)使用方括号 [] 或list() 创建,元素间用逗号 , 分隔

3)列表中各元素类型可以不同,无长度限制

 

案例:

ls = ["cat", "dog","tiger", 1024]
ls
['cat', 'dog', 'tiger', 1024] 

#赋值
lt = ls
 lt
['cat', 'dog', 'tiger', 1024]
#注意:列表是引用类型,附值只是引用传递,传递地址,并没有开辟一个新的空间,新的列表

注意:方括号 [] 真正创建一个列表(开辟一个新的空间),赋值仅传递引用

 

2.操作函数和方法

 

 

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 = ["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']

 

 

 

 

6.2.5序列类型应用场景

 数据表示:元组 和 列表

1)元组用于元素不改变的应用场景,更多用于固定搭配场景

2)列表更加灵活,它是最常用的序列类型

3)最主要作用:表示一组有序数据,进而操作它们

 

  • 应用场景一

 

 

  • 应用场景二   数据保护 :如果不希望数据被程序所改变,转换成元组类型,比如函数返回值

 

 

 

 

 

6.3 实例9: 基本统计值计算 

 需求:给出一组数,对它们有个概要理解

该怎么做呢?  总个数、求和、平均值、方差、中位数…

  • 总个数:len()
  • 求和:for … in 
  • 平均值:求和/总个数
  • 方差: 各数据与平均数差的平方和的平均数 
  • 中位数:排序,然后… 奇数找中间1个,偶数找中间2个取平均

案例:

def getNum(): #获取不定长输入,没输入一个数字要回车
    nums = []
    strs = input("请输入数字,按enter键结束:")
    while strs != "":
        nums.append(eval(strs))
        strs = input("请输入数字,按enter键结束:")
    return nums

def meam(numStr):# 求平均数
    sum = 0
    for num in numStr:
        sum = sum + num
    return sum / len(numStr)

def dev(numStr, mean): #计算方差
    sdel = 0.0
    for num in numStr:
        sdel = (num - mean) ** 2 +sdel
    return sdel / len(numStr)

def median(numStr):
    sorted(numStr)
    size = len(numStr)
    if (size % 2 == 0):
        dem = (numStr[size/2-1] + numStr[size/2]) / 2
    else:
        dem = numStr[size//2]
    return dem
numStr = getNum()
meam = meam(numStr)
print("平均值:{},方差:{:.2},中位数:{}.".format(meam, dev(numStr, meam), median(numStr)))

 

6.4 字典类型及操作 

6.4.1字典类型定义

1)字典类型的定义

  • 理解“映射”

    映射是一种键(索引)和值(数据)的对应

 

  • 序列类型由0..N整数作为数据的默认索引 ,字典类型则由用户自定义索引
  • 字典类型是“映射”的体现

    1)键值对:键是数据索引的扩展,key-val

    2)字典是键值对的集合,键值对之间无序

    3)采用大括号{}和dict()创建,键值对用冒号:   表示 {<键1>:<值1>, <键2>:<值2>, … , <键n>:<值n>}

 

2)字典类型的用法

在字典变量中,通过键获得值;[ ] 用来向字典变量中索引或增加元素

用法:

<字典变量> = {<键1>:<值1>, … , <键n>:<值n>} #定义,或者dict()
<值> = <字典变量>[<键>] #索引
<字典变量>[<键>] = <值>  #增加 key-val,或者修改value

案例:

d = {"中国":"北京", "美国":"华盛顿", "法国":"巴黎"}
print(d) 
{'中国': '北京', '美国': '华盛顿', '法国': '巴黎'}

d["中国"]
'北京'

de = {} ; 
type(de);# 获取de的类型
<class 'dict'>

 

 

 

6.4.2字典处理函数及方法

pop、popitem都是返回并且删除返回的键值对

items()把每一对键值对组成一个元组类型,返回 。例如:('the', 1138)

 

 

 

 

 

 

6.4.3字典类型应用场景

  • 映射的表达

    映射无处不在,键值对无处不在

    例如:统计数据出现的次数,数据是键,次数是值

    最主要作用:表达键值对数据,进而操作它们

  • 元素遍历  键就是d

 

 

6.5 模块5: jieba库的使用

6.5.1jieba库概述

jieba是优秀的中文分词第三方库

1)中文文本需要通过分词获得单个的词语 

2)jieba是优秀的中文分词第三方库,需要额外安装

3)jieba库提供三种分词模式,最简单只需掌握一个函数

6.5.2jieba库的安装

(cmd命令行) pip install jieba

 

 

6.5.3jieba分词的原理

jieba分词依靠中文词库

1)利用一个中文词库,确定中文字符之间的关联概率 

2)中文字符间概率大的组成词组,形成分词结果

3)除了分词,用户还可以添加自定义的词组

6.5.4jieba库使用说明

1)三种模式

  • 精确模式:把文本精确的切分开,不存在冗余单词

  jieba.lcut("中国是一个伟大的国家") ['中国', '是', '一个', '伟大', '的', '国家']

 

  • 全模式:把文本中所有可能的词语都扫描出来,有冗余

  jieba.lcut("中国是一个伟大的国家",cut_all=True) ['中国', '国是', '一个', '伟大', '的', '国家']

 

  • 搜索引擎模式:在精确模式基础上,对长词再次切分

  jieba.lcut_for_search(“中华人民共和国是伟大的") ['中华', '华人', '人民', '共和', '共和国', '中华人民共 和国', '是', '伟大', '的']

2)相关函数

 

 

 

 

 

6.6 实例10: 文本词频统计

案例1:"Hamlet英文词频统计"实例

#获取文本
def getText(str):
    txt = open(str, "r").read()
    txt = txt.lower()
    for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~':
        txt = txt.replace(ch, " ")
    return txt

hamletTxt = getText("D:\hamlet.txt")
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))

 

 

案例2:"《三国演义》人物出场统计"实例

import jieba
txt = open("D:\\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))

运行结果:

 

 

改进后:

import jieba
txt = open("D:\\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(15):
    word, count = items[i]
    print("{0:<10}{1:>5}".format(word, count))

运行结果:

 

 

 

7.文件和数据格式化

7.1 文件的使用

 7.1.1文件的类型

1)文件的理解——文件是数据的抽象和集合

  • 文件是存储在辅助存储器上的数据序列
  • 文件是数据存储的一种形式
  • 文件展现形态:文本文件和二进制文件
  • 文本文件和二进制文件只是文件的展现方式
  • 本质上,所有文件都是二进制形式存储
  • 形式上,所有文件采用两种方式展示

 2)文本文件 

  • 由单一特定编码组成的文件,如UTF-8编码
  • 由于存在编码,也被看成是存储着的长字符串
  • 适用于例如:.txt文件、.py文件等

3)二进制文件 

  •  直接由比特0和1组成,没有统一字符编码 
  • 一般存在二进制0和1的组织结构,即文件格式
  • 适用于例如:.png文件、.avi文件等

 

7.1.2文件的打开和关闭

 1)文件处理的步骤: 打开-操作-关闭

 

 

2)打开文件语法格式:

 

 文件路径和名称的写法:

 

 

3)打开模式,打开模式可省略不写,如省略默认打开方式是文本形式+只读

 

 

7.1.3文件内容的读取 

 

 

 

 

注意:of.read()是一次读入,统一处理。如果有参数则按数量读入,分行处理

    of.readlines()这是分行读入,逐步处理、

 

7.1.4数据的文件写入

 

 

 

 

7.2 实例11: 自动轨迹绘制

 需求:根据脚本来绘制图形?

  • 不通过写代码而通过写数据绘制轨迹 
  • 数据脚本是自动化最重要的第一步

 

 基本思路:

步骤1:定义数据文件格式(接口) 

 

 

步骤2:编写程序,根据文件接口解析参数绘制图形

步骤3:编制数据文件

import turtle as t
t.title('自动轨迹绘制')
t.setup(800, 600, 0, 0)
t.pencolor("red")
t.pensize(5)
#数据读取
datals = []
f = open("data.txt")
for line in f:
    line = line.replace("\n","")
    datals.append(list(map(eval, line.split(","))))
f.close()
#自动绘制
for i in range(len(datals)):
    t.pencolor(datals[i][3],datals[i][4],datals[i][5])
    t.fd(datals[i][0])
    if datals[i][1]:
        t.right(datals[i][2])
    else:
        t.left(datals[i][2])
t.done()

数据文件内容:

300,0,144,1,0,0
300,0,144,0,1,0
300,0,144,0,0,1
300,0,144,1,1,0
300,0,108,0,1,1
184,0,72,1,0,1
184,0,72,0,0,0
184,0,72,0,0,0
184,0,72,0,0,0
184,1,72,1,0,1
184,1,72,0,0,0
184,1,72,0,0,0
184,1,72,0,0,0
184,1,72,0,0,0
184,1,720,0,0,0

运行结果:

 

 

7.3 一维数据的格式化和处理

 

7.3.1数据组织的维度

  • 维度:一组数据的组织形式
  • 一维数据:由对等关系的有序或无序数据构成,采用线性方式组织。   对应列表、数组和集合等概念
  • 二维数据:由多个一维数据构成,是一维数据的组合形式。表格是典型的二维数据 其中,表头是二维数据的一部分
  • 多维数据:由一维或二维数据在新维度上扩展形成
  • 高维数据:仅利用最基本的二元关系展示数据间的复杂结构

 

 

  •  数据的操作周期:

  存储 <-> 表示 <-> 操作

 

 

 

7.3.2一维数据的表示

如果数据间有序:使用列表类型

  • 例如:ls = [3.1398, 3.1349, 3.1376]
  • 列表类型可以表达一维有序数据
  • for循环可以遍历数据,进而对每个数据进行处理

如果数据间无序:使用集合类型

  • 例如:st = {3.1398, 3.1349, 3.1376}
  • 集合类型可以表达一维无序数据
  • for循环可以遍历数据,进而对每个数据进行处理

 

7.3.3一维数据的存储

存储方式一:空格分隔

  • 例如:中国 美国 日本 德国 法国 英国 意大利
  • 使用一个或多个空格分隔进行存储,不换行
  • 缺点:数据中不能存在空格

存储方式二:逗号分隔

  • 例如:中国,美国,日本,德国,法国,英国,意大利
  • 使用英文半角逗号分隔数据进行存储,不换行
  • 缺点:数据中不能有英文逗号

存储方式三:其他方式

  • 例如:中国$美国$日本$德国$法国$英国$意大利
  • 使用其他符号或符号组合分隔,建议采用特殊符号 
  • 缺点:需要根据数据特点定义,通用性较差

 

 

7.3.4一维数据的处理

 存储 <-> 表示:

  • 将存储的数据读入程序 
  • 将程序表示的数据写入文件

 

 

 

一维数据的读入处理:

从特殊符号分隔的文件中读入数据。例如:中国$美国$日本$德国$法国$英国$意大利

txt = open(fname).read()
ls = txt.split("$")
f.close()

输出:ls= ['中国', '美国', '日本', '德国 ', '法国', '英国', '意大利']

 

一维数据的写入处理:

采用空格分隔方式将数据写入文件

ls = ['中国','美国','日本']
f = open(fname, 'w')
f.write(' '.join(ls))
f.close()

 

 

7.4 二维数据的格式化和处理

 

7.4.1二维数据的表示 

使用列表类型: 

  • 例如:使用二维列表[ [3.1398, 3.1349, 3.1376], [3.1413, 3.1404, 3.1401] ]
  • 使用两层for循环遍历每个元素
  • 外层列表中每个元素可以对应一行,也可以对应一列

 

7.4.2CSV数据存储格式

CSV: Comma-Separated Values

  • 国际通用的一二维数据存储格式,一般.csv扩展名
  • 每行一个一维数据,采用逗号分隔,无空行
  • Excel和一般编辑软件都可以读入或另存为csv文件

 

 

注意事项:

  • 如果某个元素缺失,逗号仍要保留 
  • 二维数据的表头可以作为数据存储,也可以另行存储
  • 逗号为英文半角逗号,逗号与数据之间无额外空格

 

 

 

7.4.3二维数据的存储

1)按行存或者按列存都可以,具体由程序决定

2)一般索引习惯:ls[row][column],先行后列

3)根据一般习惯,外层列表每个元素是一行,按行存

 

7.4.4二维数据的处理

 从CSV格式的文件中读入数据:

fo = open(fname)
ls = []
for line in fo:
    line = line.replace("\n","")
    ls.append(line.split(",")) 
fo.close()

将数据写入CSV格式的文件:

ls = [[], [], []] #二维列表
f = open(fname, 'w')
for item in ls:
    f.write(','.join(item) + '\n') 
f.close()

二维数据的逐一处理: 采用二层循环

ls = [[1,2], [3,4], [5,6]] #二维列表
for row in ls:
    for column in row:
    print(column)

 

 

 

7.5 模块6: wordcloud库的使用

7.5.1wordcloud库基本介绍

wordcloud库概述:

wordcloud是优秀的词云展示第三方库

 词云以词语为基本单位,更加直观和艺术地展示文本

 

wordcloud库的安装:

(cmd命令行) pip install wordcloud

 

7.5.2wordcloud库使用说明

wordcloud库把词云当作一个WordCloud对象

  • wordcloud.WordCloud()代表一个文本对应的词云 
  • 可以根据文本中词语出现的频率等参数绘制词云
  • 词云的绘制形状、尺寸和颜色都可以设定

 

wordcloud库常规方法

  • 获得WorldCloud对象:w = wordcloud.WordCloud()
  • 以WordCloud对象为基础 ,配置参数、加载文本、输出文件

 

 

 代码示例:

 

 

 从文本到词云:

 

 

配置对象参数:

 w = wordcloud.WordCloud(<参数>)

 

 

7.6 实例12: 政府工作报告词云

 

相关链接:https://python123.io/resources/pye/关于实施乡村振兴战略的意见.txt

https://python123.io/resources/pye/新时代中国特色社会主义.txt

基本思路:

 

 

# GovRptWordCloudv1.py
import jieba
import wordcloud

f = open("D:\\政府工作报告.txt", "r", encoding="utf-8")
t = f.read()
f.close()
ls = jieba.lcut(t)
txt = " ".join(ls)
w = wordcloud.WordCloud(font_path="msvc.ttc", width=1000, height=700, \
                        background_color="white", )
w.generate(txt)
w.to_file("grwordcloud.png")

 

 

优化后:

import jieba
import wordcloud
from imageio import imread  #生成特定形状的词云
mask = imread("vcc.png")  #vcc.png是一只熊猫

f = open("D:\\政府工作报告.txt", "r", encoding="utf-8")
t = f.read()
f.close()
ls = jieba.lcut(t)
txt = " ".join(ls)
w = wordcloud.WordCloud(font_path = "msyh.ttc",\
    width = 1000, height = 700, background_color = "white", mask = mask,)
w.generate(txt)
w.to_file("groundcloth1.png")

 

posted @ 2022-10-10 20:35  Grit_L。  阅读(223)  评论(0编辑  收藏  举报