基础
基础
一、安装
Mac
brew install python
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
二、元组
'''
元组解释:
概述:
它属于容器类型, 是不可变类型(即, 元素内容不能修改, 注意: 元素是列表的情况除外), 和列表类似, 它也是用来存储多个元素的.
格式:
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。
三、列表
'''
需求:
幸运数字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}')
四、字典
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, 统计的是键值对的对数
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)
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)
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
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. 集的格式
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)
六、公共运算符
'''
公共运算符和函数解释:
概述:
所谓的公共运算符和公共函数的意思是, 它们既可以操作列表, 也可以操作元素, 字符串 以及 字典等.
分类:
+ 合并, 针对于: 列表, 元组, 字符串有效.
* 复制, 针对于: 列表, 元组, 字符串有效.
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') # 字符串
七、公共函数
'''
公共的函数解释:
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'
八、推导式
'''
推导式简介:
概述:
所谓的推导式就是用来简化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)
# 推导式格式:
# 列表/字典 = [表达式 如果你的表达式缺什么, 这里写什么]
九、可变和不可变类型
'''
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}')
十、切片
#模式[start:end:step]
"""
其中,第一个数字start表示切片开始位置,默认为0;
第二个数字end表示切片截止(但不包含)位置(默认为列表长度);
第三个数字step表示切片的步长(默认为1)。
当start为0时可以省略,当end为列表长度时可以省略,
当step为1时可以省略,并且省略步长时可以同时省略最后一个冒号。
另外,当step为负整数时,表示反向切片,这时start应该比end的值要大才行。
"""
aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
print (aList[::]) # 返回包含原列表中所有元素的新列表
print (aList[::-1]) # 返回包含原列表中所有元素的逆序列表
print (aList[::2]) # 隔一个取一个,获取偶数位置的元素
print (aList[1::2]) # 隔一个取一个,获取奇数位置的元素
print (aList[3:6]) # 指定切片的开始和结束位置
aList[0:100] # 切片结束位置大于列表长度时,从列表尾部截断
aList[100:] # 切片开始位置大于列表长度时,返回空列表
aList[len(aList):] = [9] # 在列表尾部增加元素
aList[:0] = [1, 2] # 在列表头部插入元素
aList[3:3] = [4] # 在列表中间位置插入元素
aList[:3] = [1, 2] # 替换列表元素,等号两边的列表长度相等
aList[3:] = [4, 5, 6] # 等号两边的列表长度也可以不相等
aList[::2] = [0] * 3 # 隔一个修改一个
print (aList)
aList[::2] = ['a', 'b', 'c'] # 隔一个修改一个
aList[::2] = [1,2] # 左侧切片不连续,等号两边列表长度必须相等
aList[:3] = [] # 删除列表中前3个元素
del aList[:3] # 切片元素连续
del aList[::2] # 切片元素不连续,隔一个删一个
创建一个支持切面的对象
import numbers
class Group:
#支持切片操作
def __init__(self, group_name, company_name, staffs):
self.group_name = group_name
self.company_name = company_name
self.staffs = staffs
def __reversed__(self):
self.staffs.reverse()
def __getitem__(self, item):
cls = type(self)
if isinstance(item, slice):
return cls(group_name=self.group_name, company_name=self.company_name, staffs=self.staffs[item])
elif isinstance(item, numbers.Integral):
return cls(group_name=self.group_name, company_name=self.company_name, staffs=[self.staffs[item]])
def __len__(self):
return len(self.staffs)
def __iter__(self):
return iter(self.staffs)
def __contains__(self, item):
if item in self.staffs:
return True
else:
return False
staffs = ["bobby1", "imooc", "bobby2", "bobby3"]
group = Group(company_name="imooc", group_name="user", staffs=staffs)
reversed(group)
for user in group:
print(user)