阿里云天池Python(二)

前言

第4-6天的课程:基本的Python基础, 不做详细罗列,这里只记录 知识体系重难点。由于这块涉及到数据结构,会较为详细~

星星

  • 困难度 ==> ★☆☆☆☆☆
  • 知识量 ==> ★★★★★★
  • 掌握度 ==> ★★★★★☆

知识体系

  1. 列表
    • 列表的定义
    • 列表的创建
    • 向列表中添加元素
    • 删除列表中的元素
    • 获取列表中的元素
    • 列表的常用操作符
    • 列表的其他方法
  2. 元组
    • 创建和访问一个元组
    • 更新和删除一个元组
    • 元组相关的操作符
    • 内置方法
    • 解压元组
  3. 字符串
    • 字符串的定义
    • 字符串的切片与拼接
    • 字符串的常用内置方法
    • 字符串格式化
  4. 字典
    • 可变类型与不可变类型
    • 字典的定义
    • 创建和访问字典
    • 字典的内置方法
  5. 集合
    • 集合的创建
    • 访问集合中的值
    • 集合的内置方法
    • 集合的转换
    • 不可变集合
  6. 序列
    • 针对序列的内置函数

重难点

列表

  1. 类型:list

  2. 特点:有序集合,元素可为不同类型,没有固定大小

  3. 表示:[,,,]

  4. 列表存放的是指向元素的指针

  5. 推导式创建列表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    x = [0] * 5
    # [0, 0, 0, 0, 0]
    x = [i for i in range(100) if (i % 2) != 0 and (i % 3) == 0]
    # [3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99]
    x = [[0] * 3] * 4
    # [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
    # ---
    a = [0] * 3
    y = [a] * 4
    y[0][0] = 1
    # [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]
  6. 函数

    插入删除涉及到位置index, 具体为下图:
    index位置

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    len(list) # 求元素个数
    # 添加元素 (如果 seq 为 list, 则 [a, b, c, [seq1, seq2, ...]])
    list.append(obj)
    # 扩展元素 (如果 seq 为 list, 则 [a, b, c, seq1, seq2, ...])
    list.extend(seq)
    list.insert(index, obj) # 插入元素
    list.remove(obj) # 删除元素
    list.pop([index=-1]) # 弹出元素
    del [start index : end index] # 删除指定范围元素
    list.count(obj) # 计算元素出现次数
    list.index(x[, start[, end]]) # 从指定的 start 到 end 中找到某元素返回索引值
    list.reverse() # 反转列表 list[::-1]
    # 排序
    # 1. key 用于排序的 index
    # 2. reverse = True 降序, reverse = False 升序(默认)。
    list.sort(key=None, reverse=False)

    # pop example
    x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
    # index: 0(-5) 1(-4) 2(-3) 3(-2) 4(-1)
    y = x.pop()
    print(y) # Friday
    y = x.pop(0)
    print(y) # Monday
    y = x.pop(-2)
    print(y) # Wednesday
    print(x) # ['Tuesday', 'Thursday']

    # sort example 1
    def takeSecond(elem):
    return elem[1]
    x = [(2, 2), (3, 4), (4, 1), (1, 3)]
    x.sort(key=takeSecond)
    print(x)
    # [(4, 1), (2, 2), (1, 3), (3, 4)]
    # sort example 2 lambda 表达式
    x.sort(key=lambda a: a[0])
    print(x)
    # [(1, 3), (2, 2), (3, 4), (4, 1)]

    # 浅拷贝与深拷贝
    list1 = [123, 456, 789, 213]
    list2 = list1
    list3 = list1[:]

    print(list2) # [123, 456, 789, 213]
    print(list3) # [123, 456, 789, 213]
    list1.sort()
    print(list2) # [123, 213, 456, 789]
    print(list3) # [123, 456, 789, 213]

    list1 = [[123, 456], [789, 213]]
    list2 = list1
    list3 = list1[:]
    print(list2) # [[123, 456], [789, 213]]
    print(list3) # [[123, 456], [789, 213]]
    list1[0][0] = 111
    print(list2) # [[111, 456], [789, 213]]
    print(list3) # [[111, 456], [789, 213]]
  7. 操作符

    • 等号操作符 == (元素相同且位置相同)
    • 连接操作符 + ( = extend() )
    • 重复操作符 * (只能 * 整数)
    • 成员关系操作符 innot in

元组

  1. 类型:tuple
  2. 特点:有序集合,元素可为不同类型,固定大小,不可修改 ( immutable )
  3. 表示:(,,,)
  4. 列表存放的是指向元素的指针
  5. 元组和列表都属于序列
  6. 列表属于可变序列,它的元素可以随时修改或者删除,而元组属于不可变序列,其中的元素是不能修改的,除非整体重新赋值。
  7. 列表可以使用多种方法实现添加和修改列表元素,而元组没有办法,因为不能想元组中添加或修改元素,同样也不能删除元素
  8. 列表可以使用切片方法访问和修改列表中的元素,元组也支持切片,但是它只支持通过切片访问元组中的元素,不支持修改
  9. 元组比列表中的访问和处理速度更快,所以如果只需要对其中的元素进行访问,而不进行任何修改,建议使用元组。
  10. 列表不能作为字典类型中的键,而元组是可以的。
  11. 元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
x = (1) # <class 'int'>
x = (1,) # <class 'tuple'>
print(8 * (8)) # 64
print(8 * (8,)) # (8, 8, 8, 8, 8, 8, 8, 8)
x = ((1, 10.31, 'python'), ('data', 11))

# 只能整体赋值来修改元组
week = ('Monday', 'Tuesday', 'Thursday', 'Friday')
week = week[:2] + ('Wednesday',) + week[2:]

# 内置方法只有2个
t = (1, 10.31, 'python')
print(t.count('python')) # 1
print(t.index(10.31)) # 1

  1. 解压元组

解压元组挺有趣的,第一次听说和使用的是隔壁 JS 的 ES6 的语法 ~
ES6 - 解构赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
t = (1, 10.31, ('OK', 'python'))
(a, b, (c, d)) = t
print(a, b, c, d)
# 1 10.31 OK python

t = 1, 2, 3, 4, 5
a, b, *rest, c = t
print(a, b, c) # 1 2 5
print(rest) # [3, 4]

t = 1, 2, 3, 4, 5
a, b, *_ = t
print(a, b) # 1 2

字符串

  1. 可以用单引号也可以双引号, 类型 str
  2. 转义
    转义字符 描述
    \\ 反斜杠符号
    \' 单引号
    \" 双引号
    \n 换行
    \t 横向制表符(TAB)
    \r 回车
1
2
3
4
5
6
7
8
9
10
11
# 前面加小 r 不转义
print("C:\\Program Files\\Intel\\Wifi\\Help")
print(r'C:\Program Files\Intel\Wifi\Help')
# C:\Program Files\Intel\Wifi\Help

# 三引号为跨行字符串,字符串中 tab \n 会被翻译
para_str = '''这是一个多行字符串的实例
多行字符串可以使用制表符
TAB ( \t )。
也可以使用换行符 [ \n ]。
'''
  1. 字符串跟元组一样不可修改性,可理解为 C 的 char[],
  2. 内置方法:
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
45
46
47
str = 'xiaoxie'
# 首字符大写
print(str.capitalize()) # Xiaoxie
# 全体小写
lower()
# 全体大写
upper()
# 大小写切换
swapcase()
# 返回字符串 str 在指定范围内出现的次数
count(str, beg=0, end=len(string))
# 返回在指定范围内是否以字符串 str 开头/结尾
startswith(substr, beg=0, end=len(string))
endswith(suffix, beg=0, end=len(string))
# 顺序/逆序查找指定范围内是否包含 str, 是返回索引,否则 -1
find(str, beg=0, end=len(string))
rfind(str, beg=0, end=len(string))
# 是否只包含数字
isnumeric()
# 左/右对齐字符串,width是长度,fillchar是填充字符。
# 有 C 的 printf("%-10d\n", 101010); 内味了
ljust(width[, fillchar])
rjust(width[, fillchar])
# 截掉字符串 左边 / 右边 / 两边 的空格或指定字符
lstrip([chars])
rstrip([chars])
strip([chars])
# 找到子字符串sub,把字符串分为一个三元组 (pre_sub, sub, fol_sub) (str, '', '')
partition(sub)
# 替换/分割,次数
replace(old, new [, max])
split(str="", num)
# 分行 keepends = True,则保留换行符
splitlines([keepends])

# 最后两个有点东西,方便加密吗
# 创建字符映射的转换表,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
maketrans(intab, outtab)
# 根据参数table给出的表,转换字符串的字符,要过滤掉的字符放到deletechars参数中。
translate(table, deletechars="")
# example
str7 = 'this is string example....wow!!!'
intab = 'aeiou'
outtab = '12345'
trantab = str7.maketrans(intab, outtab)
print(trantab) # {97: 49, 111: 52, 117: 53, 101: 50, 105: 51}
print(str7.translate(trantab)) # th3s 3s str3ng 2x1mpl2....w4w!!!
  1. 格式化

    printf 换汤不换药,不多介绍。

    符号 描述
    %c 格式化字符及其ASCII码
    %s 格式化字符串,用str()方法处理对象
    %r 格式化字符串,用rper()方法处理对象
    %d 格式化整数
    %o 格式化无符号八进制数
    %x 格式化无符号十六进制数
    %X 格式化无符号十六进制数(大写)
    %f 格式化浮点数字,可指定小数点后的精度
    %e 用科学计数法格式化浮点数
    %E 作用同%e,用科学计数法格式化浮点数
    %g 根据值的大小决定使用%f或%e
    %G 作用同%g,根据值的大小决定使用%f或%E

    符号 功能
    m.n m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)
    - 用作左对齐
    + 在正数前面显示加号( + )
    # 在八进制数前面显示零(‘0’),在十六进制前面显示’0x’或者’0X’(取决于用的是’x’还是’X’)
    0 显示的数字前面填充’0’而不是默认的空格
1
2
str8 = '{0:.2f}{1}'.format(27.658, 'GB')  # 保留小数点后两位
print(str8) # 27.66GB

字典

  1. 类型: dict
  2. 无序,Key唯一且不可变
    • 能hash() ==> 不可变 ==> 数值字符元组 ==> 修改后 id() 变化
    • 不能hash() ==> 可变 ==> 列表集合字典 ==> 修改后 id() 不变
  3. 字典是 Python 唯一的一个 映射类型,字符串、元组、列表属于序列类型。
  4. 表示:{k:v, k1:v1, k2:v2, k3:v3, ...}
  5. Key唯一,如果多次赋值,后面会覆盖前面的值
  6. 创建字典
1
2
3
dic1 = dict([('apple', 4139), ('peach', 4127), ('cherry', 4098)])
dic2 = dict((('apple', 4139), ('peach', 4127), ('cherry', 4098)))
dic = dict(name='Tom', age=10)
  1. 内置方法:
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
dict.fromkeys(seq) # 用一个序列作为 key 创建字典
dict.fromkeys(seq, 10) # 初始化值为10
dict.fromkeys(seq, ('小马', '8', '男')) # 初始化序列值

dict.keys() # 返回 key 序列 可外面包括 list()
dict.values() # 返回 values 序列 可外面包括 list()

dict.items() # 返回全部键值对,可用数组、元组接
dict.get(key, default=None) # get, 和 C# 类似
dict.setdefault(key, default=None) # set, 和 C# 类似

key in dict # 字面意思
key not in dict

dict.pop(key[,default]) # 弹出 Key 的键值对,Key 不存在则拿 default

# 不解释
del dict[key]
dict.clear()

# 浅复制(浅拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用)
# 如果是 直接 a = b, 则只是 a 引用 b, a 随 b 变化而变化。
dict.copy()

# 随机???弹出一个键值对,为空则报错 (奇怪的函数???)
dict.popitem()

# 很有用的函数,把 dic2 有的键值对更新到 dic, 把重复的 key 更新上 value 值。
dic.update(dic2)

集合

  1. 类型: set
  2. 无序, Key唯一且不可变, 无索引, 不可切片
  3. 表示:{,,,,}
  4. 内置函数:
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
set.add(elmnt) # 添加元素 elmnt 可为 字符串,元组,数组,可用来去除重复元素
# 不重复添加,重复不更新,可以为字典,字典只以 key 参与添加
set.update(set)

# add 和 update 不同
# update 他的工作原理是,将 [可迭代对象] 进行 [遍历] 后的元素添加到集合中
# add 不遍历,无脑加
x = {"apple", "orange", "pear"}
x.add(('a', 'b')) # {('a', 'b'), 'apple', 'orange', 'pear'}
x.update(('a', 'b')) # {'a', 'apple', 'b', 'orange', 'pear'}

set.remove(item) # 移除元素,元素不存在报错
set.discard(value) # 移除元素,元素不存在则忽略
set.pop() # 随机移除

# 交集
set.intersection(set1, set2)
set1 & set2
set.intersection_update(set1, set2) # 无返回值,赋值在 set 上

# 并集
set.union(set1, set2)
set1 | set2

# 差集
set.difference(set)
set1 - set2
set.difference_update(set) # 无返回值,赋值在 set 上

# 异或
set.symmetric_difference(set)
set1 ^ set2
set.symmetric_difference_update(set) # 无返回值,赋值在 set 上

# 在否包含(子集)
set.issubset(set)
set1 <= set2

# 是否被包含(超集)
set.issuperset(set)
set1 >= set2

# 是否有相交
set.isdisjoint(set)

冻结集合(不可变集合)

  1. 类型:frozenset([iterable])
  2. Python 提供了不能改变元素的集合的实现版本,即不能增加或删除元素,类型名叫frozenset。需要注意的是frozenset仍然可以进行集合操作,只是不能用带有update的方法。

序列

  1. 只是一个抽象概念???或者是一个通用的接口,用于实现???
  2. 序列包括(字符串、列表、元组、集合和字典),其中集合和字典不支持索引、切片、相加和相乘操作。
  3. 内置函数:
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
45
46
47
48
49
50
51
# 不解释
list(sub)
tuple(sub)
str(obj)
len(s)
reversed(seq) # 反转
max(sub) # 取元素最大值,字母按ASCII码???
min(sub)

# 这个函数有点怪怪的,返回序列iterable与可选参数start的总和。
sum(iterable[, start=0])

# 排序
# iterable 可迭代对象
# key 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
# reverse False 升序(默认) True 降序
sorted(iterable, key=None, reverse=False)

t = ({"age": 20, "name": "a"}, {"age": 25, "name": "b"}, {"age": 10, "name": "c"})
x = sorted(t, key=lambda a: a["age"])
# [{'age': 10, 'name': 'c'}, {'age': 20, 'name': 'a'}, {'age': 25, 'name': 'b'}]

# 返回带索引的序列,索引从 start 开始
enumerate(sequence, [start=0])

seasons = ['Spring', 'Summer', 'Fall', 'Winter']
a = list(enumerate(seasons), 1)
# [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

# 压缩函数,有点东西
# 将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象
# 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同
# 利用 * 号操作符,可以将元组解压为列表。
zip(iter1 [,iter2 [...]])
a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]

zipped = zip(a, b)
print(zipped) # <zip object at 0x000000C5D89EDD88>
print(list(zipped)) # [(1, 4), (2, 5), (3, 6)]
zipped = zip(a, c)
print(list(zipped)) # [(1, 4), (2, 5), (3, 6)]

# 一开始不理解,实验后发现是个巨坑
# “zip对象” 是一个迭代器。 迭代器只能前进,不能后退。跟 C 的 next() 差不多
# zip(a, b) 是压缩, 外面的 zip(*)是解压, 解压后赋值a1, a2。
# *zip(a, b)容易看成是整体
a1, a2 = zip(*zip(a, b))
print(list(a1)) # [1, 2, 3]
print(list(a2)) # [4, 5, 6]

完结撒花

坚持不容易, 巨长的内容和超多的知识量(虽然不怎么难), 对新手不容易坚持,就算是有点基础的能坚持不跳过也不容易…

总结一波

  1. 基本一个套路(类型,特点,表示方法,增删改查(切片)方法,内置函数)
  2. 还行的知识点(深拷贝浅拷贝引用,推导式,解压元组,集合的运算,lambda表达式,压缩函数,maketranstranslate
  3. 奇怪的函数(可能为了某种)不知名的用途设计的吧…
    • dict.popitem()set.pop() 为啥要随机弹出
    • sum(iterable[, start=0]) 求和就求和,为啥要加上后面的参数,名字还是 start
    • 序列是 python 实现的一个数据结构还是为了教学而抽象出来的一个概念,或者是 python 抽象的一个接口,其他数据结构来实现它的函数
  4. 还有一节就可以开始机器学习啦 ~
文章作者: Shengyaqingfeng
文章链接: https://creazyboyone.github.io/AliyunTianci02/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Shengyaqingfeng's Blog