Python 学习笔记(四)

这次讲集合、列表、字典

集合类型

集合主要应用场景在于数据去重

定义

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

  • 集合类型与数学中的集合概念一致
  • 集合元素之间无序,每个元素唯一,不存在相同元素
  • 集合元素不可更改,不能是可变数据类型

  • 建立集合类型用 {} 或 set(),元素间用逗号分隔

  • 建立空集合类型,必须使用set(),因为字典

1
2
3
A = {"python", 123, ("python",123)}
B = set("pypy123") # {'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 补,返回一个新集合,包括集合 S 和 T 中的非相同元素
S <= T 或 S < T 返回 True/False,判断 S 和 T 的子集关系
S >= T 或 S > T 返回 True/False,判断 S 和 T 的包含关系
1
2
3
4
5
6
7
A = {"p", "y", 123}
B = set("pypy123") # {'y', 'p', '3', '2', '1'}
print(A - B) # {123}
print(A & B) # {'p', 'y'}
print(A ^ B) # {'1', '3', 123, '2'}
print(B - A) # {'2', '3', '1'}
print(A | B) # {'y', 'p', '3', '2', '1', 123}

集合处理方法

操作函数或方法 描述
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,x 在集合 S 中,返回 True,否则返回 False
x not in S 判断 S 中元素 x,x 不在集合 S 中,返回 True,否则返回 False
set(x) 将其他类型变量 x 转变为集合类型

序列类型

定义

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

序列是一个基类类型,其下引申出:字符串类型元组类型列表类型

序列类型通用操作符

操作符 描述
x in s 如果 x 是序列 s 的元素,返回 True,否则返回 False
x not in s 如果 x 是序列 s 的元素,返回 False,否则返回 True
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 为步长的元素子序列

序列类型通用函数和方法

函数和方法 描述
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 的总次数

元组类型

元组是序列类型的一种扩展

  • 元组是一种序列类型,一旦创建就不能被修改
  • 使用小括号 () 或 tuple() 创建,元素间用逗号 , 分隔
  • 可以使用或不使用小括号
  • 元组继承了序列类型的全部通用操作
1
2
3
4
creature = "cat", "dog", "tiger", "human"
print(creature) # ('cat', 'dog', 'tiger', 'human')
color = (0x001100, "blue", creature)
print(color) # (4352, 'blue', ('cat', 'dog', 'tiger', 'human'))

列表类型

列表是序列类型的一种扩展

  • 列表是一种序列类型,创建后可以随意被修改
  • 使用方括号 [] 或 list() 创建,元素间用逗号 , 分隔
  • 方括号 [] 真正创建一个列表,赋值仅传递引用
  • 列表中各元素类型可以不同,无长度限制

列表类型操作函数和方法

函数或方法 描述
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.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.sort(key=None, reverse=False) 对原列表进行排序

基本统计值计算示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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 += 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):
sorted(numbers)

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)))

字典类型

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

  • 字典是键值对的集合,键值对之间无序
  • 采用大括号 {} 和 dict() 创建,键值对用冒号 : 表示

字典处理函数和方法

函数或方法 描述
del d[k] 删除字典 d 中键 k 对应的数据值
k in d 判断键 k 是否在字典 d 中,如果在返回 True,否则 False
d.keys() 返回字典 d 中所有的键信息
d.values() 返回字典 d 中所有的值信息
d.items() 返回字典 d 中所有的键值对信息
d.get(k, <默认>) 键 k 存在,则返回相应值,不在则返回<默认>值
d.pop(k,<默认>) 键 k 存在,则取出相应值,不在则返回<默认>值
d.popitem() 随机从字典 d 中取出一个键值对,以元组形式返回
d.clear() 删除所有的键值对
len(d) 返回字典 d 中元素的个数

中文分词库 jieba

安装

1
pip3 install jieba
  • jieba.lcut(s) 精确模式,返回一个列表类型的分词结果

    1
    2
    jieba.lcut("中国是一个伟大的国家")
    # ['中国', '是', '一个', '伟大', '的', '国家']
  • jieba.lcut(s,cut_all=True) 全模式,返回一个列表类型的分词结果,存在冗余

    1
    2
    jieba.lcut("中国是一个伟大的国家",cut_all=True)
    # ['中国', '国是', '一个', '伟大', '的', '国家']
  • jieba.lcut_for_search(s) 搜索引擎模式,返回一个列表类型的分词结果,存在冗余

    1
    2
    jieba.lcut_for_search("中华人民共和国是伟大的")
    # ['中华', '华人', '人民', '共和', '共和国', '中华人民共和国', '是', '伟大', '的']
  • jieba.add_word(w) 向分词词典增加新词 w

Hamlet英文词频统计示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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(0, 10):
word, count = items[i]
print("{:<10}{:>5}".format(word, count))

# the 1138
# and 965
# to 754
# of 669
# you 550
# i 542
# a 542
# my 514
# hamlet 462
# in 436

《三国演义》人物出场统计示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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(0, 10):
word, count = items[i]
print("{0:<10}{1:>5}".format(word, count))

# 曹操 1451
# 孔明 1383
# 刘备 1252
# 关羽 784
# 张飞 358
# 吕布 300
# 赵云 278
# 孙权 264
# 司马懿 221
# 周瑜 217