# 基础

# 一、安装

# Mac

brew install python
1
Python has been installed as
  /opt/homebrew/bin/python3

Unversioned symlinks `python`, `python-config`, `pip` etc. pointing to
`python3`, `python3-config`, `pip3` etc., respectively, have been installed into
  /opt/homebrew/opt/python@3.9/libexec/bin

You can install Python packages with
  pip3 install <package>
They will install into the site-package directory
  /opt/homebrew/lib/python3.9/site-packages

tkinter is no longer included with this formula, but it is available separately:
  brew install python-tk@3.9

See: https://docs.brew.sh/Homebrew-and-Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 二、元组

'''
元组解释:
    概述:
        它属于容器类型, 是不可变类型(即, 元素内容不能修改, 注意: 元素是列表的情况除外), 和列表类似, 它也是用来存储多个元素的.
    格式:
        tuple1 = tuple()
        tuple2 = (10, 20, 30)
        tuple2 = (10,)
    元组和列表的区别:
        1. 定义格式不同, 元组用(), 列表用[]
        2. 关于是否可以修改元素内容, 元组不可以, 列表可以.
'''
# 需求1: 元组的定义格式.
t1 = tuple()
t2 = (10, 20, 'abc', True)
t3 = (10,)
print(type(t1), type(t2), type(t3))
print('-' * 13)

# 需求2: 演示元组的内容不能修改.
t1 = (10, 20, 30)
print(t1[1])  # 20, 获取元素值.

# t1[1] = 200  # 报错
# 特殊情况, 元组的元素是列表, 列表内容可以修改.
t1 = (10, 20, ['a', 'b', 'c'])
t1[2][1] = 'bb'  # 可以修改列表值.
# t1[2] = [11, 22]  # 报错
print(t1)
print('-' * 13)

# 元组的相关函数.
t1 = (10, 20, ['a', 'b', 'c', 'b'], ['b', 'd'], 20, 30, 20)

# print(t1.index('a'))  # 报错, 因为是在元组中直接找的, 而不是在元组的列表中继续找.
# print(t1.index(20))  # 1

print('a' in t1)  # False
print('a' not in t1)  # True
print(t1.count(20))  # 3, 统计次数.

# 幸运数字6:输入任意数字,如数字8,生成nums列表,元素值为1~8,
# 从中选取幸运数字(能够被6整除)移动到新列表lucky,
# 打印nums与lucky。
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

# 三、列表

'''
需求:
    幸运数字6:输入任意数字,如数字8,生成nums列表,元素值为1~8,
    从中选取幸运数字(能够被6整除)移动到新列表lucky,
    打印nums与lucky。

进阶版幸运数字:(约瑟夫环)
    1. 提示用户录入1个数字, 并接收.
    2. 生成1到这个数字之间所有的数字, 形成列表.
    3. 然后开始玩儿"杀人游戏", 从1开始数, 只要是数到了3或者3的倍数, 就干掉这个数字.
    4. 直至剩下最后1个数字, 它就是幸运数字.
'''

# 1. 提示用户录入1个数字, 并接收.
num = eval(input('请录入1个整数: '))
# 2. 定义列表, 用来存储数据.
# num_list = []

# 3. 根据用户录入的数字, 生成对应的数据, 并存储到列表中.
# 方式1: 用for 或者 while, 普通方式实现.
# for i in range(1, num + 1):
#     num_list.append(i)

# 采用列表推导式实现.
num_list = [i for i in range(1, num + 1)]
print(f'原始列表: {num_list}')

# 4. 定义一个新的列表, 用来存储幸运数字.
luck_list = []

# 5. 遍历数字列表, 获取到每一个数字.
for i in num_list:
    # 6. 判断当前数字是否是幸运数字(6的倍数), 如果是, 就: 将该数字添加到幸运列表中.
    # 细节: 你考虑的"移动"如果是复制, 那就添加一次就行了, 如果是"剪切", 记得从数字列表中删除该元素.
    if i % 6 == 0:
        luck_list.append(i)  # 添加到幸运数字列表
        num_list.remove(i)  # 根据元素删除内容, 从数字列表删除.

# 7. 遍历幸运列表.
print(f'操作后的幸运数字列表: {luck_list}')
print(f'操作后的数字列表: {num_list}')
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

# 四、字典

# 4.1 字典入门

'''
字典简介:
    概述:
        所谓的字典指的是dict, 它主要存储双列数据(键值对, 左边叫键, 右边叫值), 可以存储多个元素.
        所以它也是容器类型, 且是可变的容器类型.
    细节:
        1. 存储的是双列数据(也叫 键值对)
        2. 键必须是唯一的, 可以是"单值"类型, 例如: int, float, bool, 也可以是不可变的容器类型, 例如: str, 元组等
           如果是 列表 则不可以.
        3. 值可以是任意的类型.
        4. 因为以后我们经常做的事儿是, 根据键获取其对应的值, 所以: 键必须是唯一的.
'''
# 需求1: 演示字典的定义.
dict1 = {}
dict2 = dict()
dict3 = {'name': '刘亦菲', 'age': 33, 'address': '北京'}
print(type(dict1), type(dict2), type(dict3))
print('-' * 13)

# 需求2: 演示字典的键的类型, 必须是唯一的.
dict1 = {'name': '高圆圆', 10: 'abc', True: 200, 10.3: '你好', (10, 20): [11, 22, 33]}
print(dict1)
print(type(dict1))
print(len(dict1))  # 5, 统计的是键值对的对数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 4.2 字典的CURD之增

'''
字典的CURD之 增:
    格式:
        字典名[键] = 值      # 如果键存在, 就是用新值覆盖旧值, 并返回旧值, 如果键不存在, 则是新增.
    细节:
        列表: [10, 20, 30]
        元组: (10, 20, 30)
        集:   {10, 20, 30}
        字典: {'a':10, 'b':20, 'c':30}
    结论:
        字典是容器类型, 且是 可变的 容器.
'''

# 1. 定义字典.
dict1 = {'name': '乔峰', 'age': 33}

# 2. 给字典添加元素, 键不存在.
dict1['address'] = '契丹'

# 3. 给字典添加元素, 键存在.
dict1['age'] = 83

# 4. 打印字典.
print(dict1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 4.3 字典的CURD之删和改

'''
字典的CURD之 删:
    格式:
        pop()   根据键, 删除其对应的键值对
        del     可以删除键值对, 也可以删除整个字典(内存中没有了)
        clear() 清空字典, 即内容都没有了, 但是字典还在.

字典的CURD之 改:
    格式:
       字典名[键] = 值      # 键存在就是修改, 键不存在就是 新增(添加)
'''
# 1. 定义字典.
dict1 = {'name': '虚竹', 'age': 28}

# 2. 演示修改元素.
dict1['age'] = 30

# 3. 演示 pop() 根据键, 删除其对应的键值对, 键存在就删除, 且返回值.
print(dict1.pop('name'))   # 虚竹
# print(dict1.pop('address'))  # 键不存在, 就报错

# 4. 演示 del
del dict1['name']   # 根据键, 删除其对应的键值对, 键不存在, 就报错
# del dict1['names']  # 根据键, 删除其对应的键值对, 键不存在, 就报错
# del dict1  # 从内存中删除该字典.

# 5. 演示 clear()
dict1.clear()

# 6. 打印结果.
print(dict1)
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

# 4.4 字典的CURD之查

'''
字典的CURD之 查:
    格式:
        字典名[键]          根据键获取其对应的值, 键不存在就报错.
        字典名.get(键)      根据键获取其对应的值, 键不存在就返回None
        keys()              获取到所有的键.
        values()            获取到所有的值
        items()             获取到所有的键值对.
'''
# 1. 定义字典.
dict1 = {'name': '段誉', 'age': 19, 'address': '大理', 'wifes': ['王语嫣', '穆婉清', '钟灵儿'], '慕容复': '王语嫣', '马然': '王语嫣'}

# 2. 演示 根据键获取其对应的值.
print(dict1['name'])
# print(dict1['names']) 报错
print(dict1.get('name'))
print(dict1.get('names'))  # 不报错, 返回None
print('-' * 13)

# 3. 字典中没有根据值获取键的操作, 因为值可以是重复的.
print(dict1['慕容复'])  # 王语嫣, 根据键获取值
print(dict1['马然'])  # 王语嫣, 根据键获取值, 因为值可以重复, 所以根据值获取键没有意义, 或者说压根不支持.
print('-' * 13)

# 4. 获取所有的键.
print(dict1.keys())
print(type(dict1.keys()))  # dict_keys
print('-' * 13)

# 5. 获取所有的值.
print(dict1.values())
print(type(dict1.values()))  # dict_values
print('-' * 13)

# 6. 获取所有键值对的集合.
print(dict1.items())
print(type(dict1.items()))  # dict_items
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

# 4.5 字典的遍历

'''
字典的遍历:
    入门班:
        版本1: 直接遍历字典, 相当于遍历所有的键.
        版本2: 遍历所有的键.
        版本3: 遍历所有的值.
        上述的这3个版本, 都只是铺垫, 为了给后续的内容做铺垫的, 下边的两个版本, 必须掌握.
    进阶版:
        方式1: 根据键获取其对应的值, 也叫: 根据丈夫找妻子.
        方式2: 根据键值对获取其对应的键和值, 也叫: 根据结婚证找丈夫和妻子.
'''
# 1. 定义字典.
dict1 = {'name': '段誉', 'age': 19, 'address': '大理'}

# 版本1: 直接遍历字典, 相当于遍历所有的键.
for i in dict1:
    print(i)  # i 就是每一个键.
print('-' * 13)

# 版本2: 遍历所有的键.
for i in dict1.keys():
    print(i)  # i 就是每一个键.
print('-' * 13)

# 版本3: 遍历所有的值.
for i in dict1.values():
    print(i)  # i 就是每一个值.
print('-' * 13)

# 进阶版, 都要掌握.
# 方式1: 根据键获取其对应的值, 也叫: 根据丈夫找妻子.
for key in dict1.keys():        # 掌握
    # print(f'{key} = {dict1.get(key)}')
    print(f'{key} = {dict1[key]}')
print('-' * 13)

# 方式2: 根据键值对获取其对应的键和值, 也叫: 根据结婚证找丈夫和妻子.
for item in dict1.items():
    # item的格式:   ('name', '段誉')  这个是 元组
    print(f'{item[0]} = {item[1]}')
print('-' * 13)

# 方式2的优化版.
# 每一个item的格式:   ('name', '段誉')  这个是 元组
for k,v in dict1.items():       # 掌握
    print(f'{k} = {v}')
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

# 五、集合

'''
集介绍:
    概述:
        所谓的集指的就是集合, 它的元素特点是: 唯一(去重), 无序(元素的存取顺序不一致, 而不是排序)
    常用的思路:
        对列表元素去重.
    流程:
        列表 -> 集, 自动去重 -> 再添加到列表中.
'''
# 1. 集的格式
set1 = set()
set2 = {10, 20, 30, 10, 30, 20, 55, 33}
print(type(set1), type(set2))

print(set2)  # 元素特点: 去重, 无序, {33, 10, 20, 55, 30}
print('-' * 13)

# 需求2: 对以下列表中的数据进行去重操作.
list1 = [10, 20, 30, 20, 10, 'aa', True, 20]

# 把列表中的数据添加到集中, 它会自动去重.
set1 = set(list1)
# 清空列表元素.
list1.clear()
# 然后把去重后的数据, 重新添加到列表中.
list1 = list(set1)
# 打印结果.
print(list1)
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

# 六、公共运算符

'''
公共运算符和函数解释:
    概述:
        所谓的公共运算符和公共函数的意思是, 它们既可以操作列表, 也可以操作元素, 字符串 以及 字典等.
    分类:
        +   合并, 针对于: 列表, 元组, 字符串有效.
        *   复制, 针对于: 列表, 元组, 字符串有效.
        in  判断是否在(包含), 针对于: 列表, 元组, 字符串, 字典有效.
        not in 判断是否不在(不包含), 针对于: 列表, 元组, 字符串, 字典有效.
'''
# 演示 +   合并, 针对于: 列表, 元组, 字符串有效.
print('abc' + 'xyz')  # 演示字符串合并.
print([10, 20] + ['aa', 'bb'])  # 演示列表合并.
print((10, 20) + ('aa', 'bb'))  # 演示元组合并.

# 演示 *   复制, 针对于: 列表, 元组, 字符串有效.
print('-' * 21)
print([11, 22] * 3)
print(('aa', 'bb') * 5)
print('-' * 21)

# 演示 in  判断是否在(包含), 针对于: 列表, 元组, 字符串, 字典有效.
print('aa' in [10, 20, 'aa', 'bb', 'cc'])  # 列表
print('aa' in (10, 20, 'aa', 'bb', 'cc'))  # 元组
print('aa' in 'abcdefgaabbcc')  # 字符串
print('aa' in 'abcdefgabbacc')  # 字符串
print('-' * 21)

# 演示 not in 判断是否不在(不包含), 针对于: 列表, 元组, 字符串, 字典有效.
print('aa' not in [10, 20, 'aa', 'bb', 'cc'])  # 列表
print('aa' not in (10, 20, 'aa', 'bb', 'cc'))  # 元组
print('aa' not in 'abcdefgaabbcc')  # 字符串
print('aa' not in 'abcdefgabbacc')  # 字符串
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

# 七、公共函数

'''
公共的函数解释:
    len()   元素的个数, 即: 容器长度.
    max()   最大值
    min()   最小值
    del    删除
    range() 生成指定范围的数据.
    enumerate() 可以对数据进行拉链操作.
'''
# 演示 len()   元素的个数, 即: 容器长度.
print(len([10, 20, 30]))
print(len((10, 20, 30, 55)))
print(len({10, 20}))
print(len({10: 20, 'a': 'b'}))
print('-' * 13)

# 演示 max()   最大值
print(max([11, 55, 33, 22]))
print(max((11, 55, 33, 22)))
print(max({11, 55, 33, 22}))
print(max({'aa': 10, 'abc': 20, 'xy': 20}))  # 内容优先, 内容一致, 长度为准.
print('-' * 13)

print(max(['张三', '李四', '王五', '小刘', '夯哥']))
print('-' * 13)

# 演示 min()   最小值
# 略.

# 演示 del    删除
# 略.

# 演示 range() 生成指定范围的数据.
# 略.

# 演示 enumerate() 可以对数据进行拉链操作.
# 需求: 把索引和元素拉到一起, 形成: 字典.
list1 = ['a', 'b', 'c']
# for i in enumerate(list1):
#     print(i)  # 0 -> 'a', 1 -> 'b', 2 -> 'c'

# 还可以设置 索引的初始值.
for i in enumerate(list1, 5):
    print(i)  # 5 -> 'a', 6 -> 'b', 7 -> 'c'
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

# 八、推导式

'''
推导式简介:
    概述:
        所谓的推导式就是用来简化Python代码的.
    分类:
        列表推导式       # 掌握
        元组推导式
        字典推导式
'''

# 需求1: 生成 1 ~ 10的列表
list1 = [i for i in range(1, 11)]
print(list1)
print('-' * 13)

# 需求2: 生成 1 ~ 10之间所有的偶数列表.
# list2 = [i for i in range(1, 11) if i % 2 == 0]
# print(list2)

list3 = [i for i in range(2, 11, 2)]
print(list3)
print('-' * 13)

# 需求3: 快速生成元素列表, 例如: [(1,1), (1,2), (1,3), (2,1), (2,2), (2,3)]
list4 = [(i, j) for i in range(1, 3) for j in range(1, 4)]
print(list4)
# for i in range(1,3):
#     for j in range(1, 4)


# 需求4: 键是数字, 值是它的平方, 例如: 1 -> 1, 2 -> 4, 3 -> 9...
dict1 = {i: i ** 2 for i in range(1, 6)}
print(dict1)

# 需求5: 类似于enumerate()的拉链操作.
list1 = ['乔峰', '虚竹', '段誉']
list2 = ['阿朱', '梦姑', '王语嫣']
#       列表1        列表2
dict2 = {list1[i]: list2[i] for i in range(len(list1))}  # i的值: 0, 1, 2
print(dict2)

# 推导式格式:
# 列表/字典 = [表达式 如果你的表达式缺什么, 这里写什么]
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

# 九、可变和不可变类型

'''
Python中的 可变和不可变类型 问题:
    概述:
        如果在不改变引用的情况下, 能修改内容, 则该类型就是: 可变类型.
        如果在不改变引用的情况下, 不能修改内容, 则该类型就是: 不可变类型.

    结论(细节, 要求记忆):
        1. 在Python中, 所有的传递, 传递的都是: 地址值.
        2. 如果形参是可变类型, 则形参的改变....
        3. 如果形参是不可变类型, 则形参的改变...
        4. Python中的类型, 按照可变类型和不可变类型具体划分如下:
            可变类型: list, dict
            不可变类型: int, float, str, bool, tuple
'''

# 演示可变类型
# 1. 定义列表
list1 = [10, 20, 30]
# 2. 打印列表内容, 及其引用.
# [10, 20, 30] 2360964923328
print(list1, id(list1))
# 3. 修改列表内容.
list1[1] = 200
# 4. 打印列表内容, 及其引用.
# [10, 200, 30] 2360964923328
print(list1, id(list1))
print('-' * 13)

# 演示不可变类型
# 1. 定义整数
a = 10
# 2. 打印整数内容, 及其引用.
print(a, id(a))  # 10, 140729342810048
# 3. 修改整数内容.
a = 20
# 4. 打印整数内容, 及其引用.
print(a, id(a))  # 20, 140729342810368

'''
需求:
    我们知道元组属于不可变类型, 但是如果元组中的某个元素是列表, 而列表的内容是可以变化的, 那么不就是说明元组是可变的吗?
    怎么理解这个问题呢?
答案:
    元组肯定是不可变类型, 这个是毋庸置疑的, 这里的不可变指的是: 元素的引用(地址值)不能变,
    但是元素如果是可变类型, 则修改它的元素值是没有问题的.
    例如: 这里的列表地址没有变化, 但是内容变化了, 也无所谓, 因为元组存的是列表的地址.
'''

# 1. 定义元组.
tuple1 = (10, [11, 22])
# 2. 打印元组内容 和 地址值.
print(tuple1, id(tuple1))
# 3. 修改元组的列表的元素值.
tuple1[1][0] = 100
# tuple1[1] = ['a', 'b']    报错
# 4. 打印元组内容 和 地址值.
print(tuple1, id(tuple1))


'''
Python中的 参数传递 问题:
    概述:
        如果在不改变引用的情况下, 能修改内容, 则该类型就是: 可变类型.
        如果在不改变引用的情况下, 不能修改内容, 则该类型就是: 不可变类型.

    结论(细节, 要求记忆):
        1. 在Python中, 所有的传递, 传递的都是: 地址值.
        2. 如果形参是可变类型, 则形参的改变直接影响实参.
        3. 如果形参是不可变类型, 则形参的改变对实参没有任何影响.
        4. Python中的类型, 按照可变类型和不可变类型具体划分如下:
            可变类型: list, dict
            不可变类型: int, float, str, bool, tuple
'''

# 演示: 如果形参是不可变类型, 则形参的改变对实参没有任何影响.
# 1. 定义变量.
a = 10
# 2. 打印变量.
print(f'函数调用前, a = {a}') # 10
# 3. 定义函数, 并且修改 上述变量(类型)的值.
def show(a):    # int, 形参, 不可变类型
    a = 200

# 4. 调用函数.
show(a)  # 实参

# 5. 重新打印变量.
print(f'函数调用后, a = {a}') # 10
print('-' * 13)

# 演示: 如果形参是可变类型, 则形参的改变直接影响实参.
# 1. 定义变量.
list1 = ['aa', 'bb', 'cc']
# 2. 打印变量.
print(f'函数调用前, list1 = {list1}') #
# 3. 定义函数, 并且修改 上述变量(类型)的值.
def func(list1):    # int, 形参, 不可变类型
    list1[1] = 'ff'

# 4. 调用函数.
func(list1)  # 实参

# 5. 重新打印变量.
print(f'函数调用后, list1 = {list1}')
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
更新时间: 1/9/2023, 2:02:13 PM