Python基础——(一)

软件:PyCharm2023.2.5,Python3.12.4

目录

1. 输出

2. 输入

3. 注释与流程控制语句 控制跳转语句

3.1 注释

3.2 流程控制语句

3.3 控制跳转语句

4. 变量及数据类型

4.1 变量

4.2 数据类型

4.3 类型转换

5. 标识符和关键字

5.1 标识符

5.2 关键字

6. 运算符和组包拆包

6.1 运算符

6.2 组包拆包

7. 容器类型

7.1 字符串str

练习题

7.2 列表list

7.3 元组

7.4 字典

练习题

7.5 集合

关于包左包右

8. 函数

练习题


1. 输出

概述: 就是把 内容 打印到控制台上

格式: print('要输出的内容')

输出的几种方式:

        (1) 直接打印变量值.

        (2) 直接打印变量名.

        (3) 同时打印多个变量值(或者变量名)

        (4) 输出, 默认换行, 即end='\n', 手动指定end的值end='\t', 表示一个Tab的空格距离, end=''表示没有间距

        (5) 格式化输出 -> %s代表字符串, %f代表小数, %d代表整数

        (6) 格式化输出 -> f'内容 {变量名} 内容'

# 定义变量, 并赋值
name = '乔峰'
age = 38
weight = 120.5
# 打印结果
print(name, 'age', 188, end='\t')  # 打印多个变量, 中间自动空出一个空格, 乔峰 age 188
print('aa', 'bb', 'cc')  # aa bb cc
print('aa' + 'bb' + 'cc')  # aabbcc
print()  # 换行操作
# 格式化输出, 特殊: 百分号前需要加%, 引号前需要加转义符\
print('你好, 我叫: %s, 年龄: %d, 这是%%百分号, 这是\'引号' % (name, age))  # 你好, 我叫: 乔峰, 年龄: 38, 这是%百分号
print(f'你好, 我叫: {name}, 年龄: {age}, 这是%百分号')  # 你好, 我叫: 乔峰, 年龄: 38, 这是%百分号
# 浮点型数据, 保留2位小数: %.2f  :.2f
print('体重: %.2f' % weight)  # 体重: 120.50
print(f'体重: {weight:.2f}')  # 体重: 120.50
# 整数, 不够5位, 前面用 空格 补齐
print('年龄: %5d' % age)  # 年龄:    38
print(f'年龄: {age:5d}')  # 年龄:    38
# 整数, 不够5位, 前面用 0 补齐, 只能用空格或者0补齐, 其他的不能
print('年龄: %05d' % age)  # 年龄: 00038
print(f'年龄: {age:05d}')  # 年龄: 00038

2. 输入

Python中的输入指的是input()函数, 接收的数据默认都是字符串类型

格式: 变量名 = input('提示的内容')

# age = eval(input('请输入您的年龄: '))    # eval去引号
age = '18'  # 为了便于测试, 这里赋值'18'
print(f'您的年龄是: {age}, age的类型是: {type(age)}')  # 您的年龄是: 18, age的类型是: <class 'str'>
# 转成整型
age_int = int(age)
print(f'age_int的类型是: {type(age_int)}')  # age_int的类型是: <class 'int'>

3. 注释与流程控制语句 控制跳转语句

3.1 注释

单行注释: # 注释内容

多行注释: 用三引号包裹即可, 可以是单引号, 也可以是双引号.

3.2 流程控制语句

概述: 指的是Python代码按照什么样的顺序来执行

分类:

(1) 顺序结构, 默认的结构, 代码按照从上往下 从左往右的顺序依次逐行执行

# 在数字运算中, 遵循运算优先级
print(5 + 5 - 3 + 2 * 3)  # 13, 乘除的优先级比加减的优先级要高

(2) 分支结构, 指的是if语句, 在满足特定的条件下, 执行的代码

# if单分支
age = 17
if age >= 18:
    print('哥已成年, 网吧可以去了!')
# if分支结构
if age >= 18:
    print('哥已成年, 网吧可以去了!')
else:
    print()
# if多分支 测试值的时候, 测试3种值: 合法值, 边界值, 非法值
if age >= 55:
    print('奖励: 游乐场通票一张')
elif age >= 35:
    print('奖励: 自助餐一次')
elif age >= 18:
    print('奖励: 练习题一套')
elif age >= 0:
    print('奖励: 玩具自选1个')
else:
    print('年龄不合法, 请重新录入')
# if嵌套
if age > 18:
    print('滴, 刷卡成功, 请上车!')
    seat = 12
    if seat > 0:
        print('有座位, 可以坐下!')
    else:
        print('无座位, 站一会儿吧!')
else:
    print('滴, 刷卡失败, 无法上车, 可以跟车跑!')

(3) 循环结构, 指的是for, while语句, 在满足特定的条件下, 重复执行的.

其中for循环, 更适用于循环次数固定的情况; while循环, 更适用于循环次数不固定的情况

# while循环
i = 1
while i <= 5:
    if i <= 3:
        print('i不超过3. ')
    print('hello world')
    i += 1
# while循环嵌套
# 打印正三角形 5行
"""
*       第一行1个
**      第二行2个
***     第三行3个
****    第四行4个
*****   第五行5个
    *      ' '*4 '*'*(1+0*2)
   ***     ' '*3 '*'*(1+1*2)
  *****    ' '*2 '*'*(1+2*2)
 *******   ' '*1 '*'*(1+3*2)
*********  ' '*0 '*'*(1+4*2)
"""
# 单个*打印
i = 1
while i <= 5:
    j = 1
    while j <= i:
        print('*', end='')
        j += 1
    print()
    i += 1
# 单行*打印
i = 0
while i <= 4:
    print(' ' * (4 - i) + '*' * (1 + i * 2))
    i += 1
# 99乘法表
i = 1
while i <= 9:
    j = 1
    while j <= i:
        print(f'{i}*{j}={i * j}', end='\t')
        j += 1
    print()
    i += 1

3.3 控制跳转语句

指的是break和continue两个关键字

break: 终止循环, 循环不再继续往下执行

continue: 结束本次循环, 开始下次循环

4. 变量及数据类型

4.1 变量

概述: 变量指的是variable, 用来临时存储数据的, 其数据值存储在内存中.

作用: 临时存储数据, 存储在内存中.

格式: 变量名 = 变量值

细节: Python是一门弱类型的语言, 对变量的数据类型没有限定的那么严格, 变量可以接收任意的值.

4.2 数据类型

概述: 用来表示 变量 的类型的

常用数据类型:

        整型 (int, 表示所有的整数), 

        浮点型 (float, 表示所有的小数), 

        布尔型 (bool, 表示所有的布尔值, 结果只有两个 True和False),

        字符串型 (str, 表示所有的字符串, 值可以单行, 可以多行, 多行要用三引号)

        列表 list()

        元组 tuple()

        字典 dict()

# 演示各类型变量
a = 10
b = 10.3
c = True
d = 'hello'
e = "world"
f = '''
hello
python!
'''
# 打印上述变量值
print(a)  # 10
print(b)  # 10.3
print(c)  # True
print(d)  # hello
print(e)  # world
print(f)  # hello
# python!
# 打印上述的变量类型
print(type(a))  # <class 'int'>
print(type(b))  # <class 'float'>
print(type(c))  # <class 'bool'>
print(type(d))  # <class 'str'>
print(type(e))  # <class 'str'>
print(type(f))  # <class 'str'>

4.3 类型转换

格式: int(变量名 或者 值), float(), bool(), str()

# int(), 转成整型, 特殊: True => 1, False => 0
print(int(True), int(False))  # 1 0
print(int(10.9))  # 10, 直接转成int丢失精度, 直接去掉小数部分
# float(), 转成标准的浮点型, 不支持设置小数位数, 特殊: True => 1.0, False => 0.0
print(float('10.3'), float('10'))  # 10.3 10.0
print(float(True), float(False))  # 1.0 0.0
# str(), 转成字符串
print(str(10.3), str(True))  # 10.3 True
# eval(), 去掉前后引号
name = 'Jam'
print(eval('name'), 'name')  # Jam name
# print(eval('张三'))                  # 报错

5. 标识符和关键字

5.1 标识符

概述: Python中用来给类, 函数, 变量等起名字的规则和规范.

命名规则:

        (1) 由数字, 字母, 下划线组成.

        (2) 数字不能开头.

        (3) 不能和Python中的关键字重名.

        (4) 最好做到见名知意.

        (5) Python是区分大小写的, 即: a 和 A不一样.

命名规范:

        (1) 类: 遵循大驼峰命名法. 例如: HelloWorld

        (2) 变量名: 遵循小驼峰命名法. 例如: helloWorld

        (3) 函数名: 遵循 蛇形命名法, 例如: get_sum

5.2 关键字

概述: 指的是key word, Python中被赋予了特殊含义的单词

# 查看Python中所有的关键字
# 导包
import keyword

# 打印Python中的所有的关键字
print(keyword.kwlist)

6. 运算符和组包拆包

6.1 运算符

概述: 用来连接变量或者变量值的符号

表达式: 用运算符连接起来的式子, 用什么运算符连接, 就叫什么表达式

        例如, a + b 叫算术表达式, a > b 叫比较(关系)表达式

分类:

        算术运算符, +, -, *, /, //(取整), %(取余), **(幂)

        赋值运算符, =

        复合赋值运算符, +=, -=, *=, /=, //=, %=, **=

        比较(关系)运算符, ==, !=, >, <, >=, <=

        逻辑运算符, and or not

        三元运算符(三元表达式)

# 赋值运算符
a, b = 10, 3
# 算术运算符
print(a + b, a - b, a * b, a / b)  # 13 7 30 3.3333333333333335
print(a // b, a % b, a ** b)  # 3 1 1000
# 复合赋值运算符
a += b  # a = a + b = 13
a -= b  # a = a - b = 10
a *= b  # a = a * b = 30
a /= b  # a = a / b = 10.0
a //= b  # a = a // b = 3.0
a %= b  # a = a % b = 0.0
a **= b  # a = a ** b = 0.0
# 比较运算符
a, b = 10, 3
print(a == b, a != b, a > b, a >= b, a < b, a <= b)  # False True True True False False
b1 = a == b
b2 = a = b
print(b1, b2, a, b)  # False 3 3 3
# 逻辑运算符
print(True and True)  # True
print(True and False)  # False
print(False and False)  # False
print(False and False)  # False
print(True or True)  # True
print(True or False)  # True
print(False or True)  # True
print(False or False)  # False
print(not True)  # False
print(not False)  # True
print(not not not False)  # True
# 三元表达式
a, b = 10, 3
max = a if a > b else b

6.2 组包拆包

组包: 把多个值 => 1个值的过程

拆包: 把1个值 => 多个值的过程, 针对于元组 列表 字典 集合 字符串有效, 如果针对于字典拆包, 只能获取键的数据

# 组包演示
s1 = 'ghijkl'
list1 = [1, 2, 3, 4, 5]
tuple1 = (1, 2, 3, 4, 5)
dict1 = {'a': 1, 'b': 2, 'c': 3}
set1 = {1, 2, 3, 4, 5}
# 拆包演示
a, b, c, d, e, f = s1           # g h i j k l
a, b, c, d, e = list1           # 1 2 3 4 5
a, b, c, d, e = tuple1          # 1 2 3 4 5
a, b, c, d, e = set1            # 1 2 3 4 5
a, b, c = dict1                 # a b c     只能获取键


7. 容器类型

容器类型: 是Python中的一个名词, 表示可以同时存储多个元素的一种数据类型

常用的容器类型: 序列(字符串str, 列表list, 元组tuple), 映射(字典dict), 集合(集合set)

字符串(str):   一个不可变的字符序列, 支持索引 切片和遍历

元组(tuple):  一个不可变的有序集合, 一旦创建后其内容不可更改, 支持索引 切片和遍历

列表(list):   一个可变的有序集合, 可以包含任意类型的元素, 支持索引 切片和遍历

字典(dict):   一个可变的键值对集合, 支持通过键快速访问对应的值, 键必须是不可变的(如字符串、元组等), 值可以是任意类型

集合(set):    一个可变的无序集合, 不允许重复元素, 支持集合操作如并集 交集和差集

容器类型公共运算符:

        +                合并(拼接),  适用于: 字符串, 列表, 元组  限于同种容器类型

        *                 复制,       适用于: 字符串, 列表, 元组  限于同种容器类型

        in               是否包含,    适用于: 字符串, 列表, 元组, 字典(只作用于键)

        not in         是否不包含,  适用于: 字符串, 列表, 元组, 字典(只作用于键)  

容器类型的公共方法:

        len()                                      获取长度的

        del                                        删除的

        max()                                    最大值

        min()                                     最小值

        range(start, end, step)          生成指定区间范围的值, 包左不包右

        enumerate()                          生成列表元素的索引和值, 封装成元组形式(索引, 值), 需要遍历出结果, 直接打印的是地址值, 类型是<class 'enumerate'>, 默认索引是从0开始的, 可以指定起始索引

推导式: 也叫解析式, 根据特定的规则生成1个数据序列的操作, 支持循环嵌套, 以及条件筛选的动作

列表推导式: [...]    格式: [变量名 for 变量名 in ... if 条件 ...]

集合推导式: {...}                                                    

字典推导式: {...}

元组没有推导式, (...)叫生成器(Generator)

引用: python中存储变量是需要占用内存空间的, 为了更好的管理这些空间, 每块空间都有自己的地址值

格式: id(变量名 或者 变量值), 可以查看变量在内存中的地址值

可变类型和不可变类型的划分依据: 在不改变地址值的情况下, 其元素值是否可以发生改变, 可以=

可变类型, 不可以=>不可变类型

可变类型: 列表, 字典, 集合

不可变类型: 字符串, 元组, 浮点型, 布尔型, 整型

# 列表推导式
print([i for i in range(10) if i % 2 == 0])                 # [0, 2, 4, 6, 8]
print([(i, j) for i in range(1, 3) for j in range(3)])      # [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# 字典推导式
print({i: i ** 2 for i in range(1, 6)})                     # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'man', 50]
#                                    这里的长度只能是长度最小的列表
print({list1[i]: list2[i] for i in range(len(list1))})      # {'name': 'Tom', 'age': 20, 'gender': 'man'}

7.1 字符串str

下标/索引:

        正向索引(从左往右或从前往后), 默认从0开始; 

        反向索引(从右往左或从后往前), 默认从-1开始;

获取字符串的某个指定字符: 字符串变量名[索引值]

遍历字符串: 通过索引方式

获取字符串长度: len()

切片: 字符串变量名[起始索引:结束索引:步长]

        起始索引默认是0(正向索引时), -1(反向索引时)

        结束索引默认是 字符串长度-1(正向索引时), 字符串长度的负数形式(逆向索引)

        步长默认是1

        如果起始索引到结束索引的方向 和 步长的方向不一致, 则获取不到数据

切片特殊写法: 字符串变量名[::-1], 表示字符串反转

字符串函数: 操作字符串变量或者字符串的一些函数

查找类:

        字符串变量名.find(要查找的子串, 起始索引, 结束索引) 找子串在字符串中第一次出现的位置, 找到就返回子串的起始索引, 找不到就返回-1

        字符串变量名.index(要查找的子串, 起始索引, 结束索引) 找子串在字符串中第一次出现的位置, 找到就返回子串的起始索引, 找不到就报错

        字符串变量名.rfind(要查找的子串, 起始索引, 结束索引) 找子串在字符串中最后一次出现的位置, 找到就返回子串的起始索引, 找不到就返回-1

        字符串变量名.rindex(要查找的子串, 起始索引, 结束索引) 找子串在字符串中最后一次出现的位置, 找到就返回子串的起始索引, 找不到就报错

替换和切割类:

        字符串变量名.replace(旧子串, 新子串, 替换次数) 用新的替换旧的, 且可以设置替换几个(如超出真实旧子串个数, 则以实际为准)

        字符串变量名.split(分隔符, 切割次数) 按照分隔符切割, 且可以设置切割次数(如超出真实切割次数, 则以实际为准)

注: 因为字符串属于不可变数据类型, 所以上述函数操作字符串后, 会返回1个新的结果, 即旧字符串不变

# 字符串正向索引, 反向索引
str1 = 'hellopython'
"""
  h   e   l   l   o   p   y   t   h   o   n 
  0   1   2   3   4   5   6   7   8   9   10
 -11 -10  -9  -8  -7  -6  -5  -4  -3  -2  -1
"""
# 字符串索引对应的值, 字符串的长度
print(str1[0], len(str1))           # h 11
# 访问字符串中每个字符
print(list(i for i in str1))        # ['h', 'e', 'l', 'l', 'o', 'p', 'y', 't', 'h', 'o', 'n']
for i in str1:
    print(i)
# 字符串切片
print(str1[::], str1[::-1])         # hellopython nohtypolleh
print(str1[:2:-2])                  # nhyo
print(str1[4:-10], str1[1:-4:-1])   # 无数据, 顺序不一致
# 字符串替换
s1 = "hello python hello world hello sql"
s2 = s1.replace('hello', 'hei')                 # 如果不写个数, 会一次性替换所有
s3 = s1.replace('hello', 'hei', 100)    # 替换次数超过真实个数时, 则以实际为准
print(s2)                           # hei python hei world hei sql
print(s3)                           # hei python hei world hei sql
# 字符串切割
s4 = s1.split(' ')                                           # 切割后, 获取的是一个字符串形式的列表
s5 = s1.split(' ', 100)                        # 切割个数超过真实个数, 以实际为准
print(s4)                           # ['hello', 'python', 'hello', 'world', 'hello', 'sql']
print(s5)                           # ['hello', 'python', 'hello', 'world', 'hello', 'sql']
# 扩展: in, not in判断指定字符是否在字符串中
print('python' in s1)               # True
print('Python' not in s1)           # True

练习题

# 练习题1: 找小串在大串中出现的次数
max_str = "hello python hello world hello sql"
min_str = 'hello'

# 思路1: 循环, 这里max_str是变动的, 一般用while True循环, 对于不变动的一般用for循环
# 定义变量, 用于小串出现次数的计数
count = 0
while True:
    # 找小串第一次出现的位置
    idx = max_str.find('hello')
    # 如果idx为-1, 说明没有找到, 此时可以结束循环
    if idx == -1:
        break
    # 计数加一
    count += 1
    # max_str切片, 跳过小串, 重新赋值
    max_str = max_str[idx + len(min_str):]
# 打印结果
print(f'小串 {min_str} 在大串中出现的次数为 {count}次')

# 思路2: 小串的长度 = (大串的长度 - 新串的长度) / 小串的长度
max_str = "hello python hello world hello sql"
min_str = 'hello'
# 替换小串为''
new_str = max_str.replace(min_str, '')
# 计算减去了多少个小串
count = (len(max_str) - len(new_str)) // len(min_str)    # /得到3.0, 改用//取整得到3
# 打印结果
print(f'小串 {min_str} 在大串中出现的次数为 {count}次')

# 思路3: 容器类型有count()函数, 容器类型有字符串str, 列表list, 元组tuple, 字典dict, 集合set
count = max_str.count(min_str)
print(f'小串 {min_str} 在大串中出现的次数为 {count}次')

# 练习题2: 交换两个变量值
a = 10
b = 3
# 思路1: 中间变量, 即临时变量
c = a
a = b
b = c
print(a, b)     # 3 10
# 思路2: 直接交换, 拆包
a, b = b, a
print(a, b)     # 10 3
# 思路3: 数值加减, 算术运算符
a = a + b       # a:a+b      b:b
b = a - b       # a:a+b      b:a
a = a - b       # a:b        b:a
print(a, b)     # 3 10
# 思路4: 位运算符(一个数字被同一个数字 位移或两次, 该数字值不变
a = a^b         # a:a^b      b:b
b = a^b         # a:a^b      b:a^b^b=a
a = a^b         # a:a^b^a=b  b:a
print(a, b)     # 10 3

7.2 列表list

可变类型: 其元素值可以直接修改

格式:

        list = [值1, 值2...]

        list = []                          # 定义空列表, 推荐这种写法

        list = list()                     # 定义空列表

索引: 也叫下标, 脚标, index, 默认从0开始(正向索引) -1(逆向索引)

切片: 支持

增:

        列表名.append(任意变量即可)          往列表的末尾追加元素

        列表名.extend(必须是容器变量)        把容器类型中的每个变量都添加到列表中

        列表名.insert(索引, 元素)                   往列表的指定位置插入元素

查:

        列表名.index(元素, 起始索引, 结束索引)   去列表中查找指定的元素(第一次出现的位置), 找不到报错

        列表名.count(元素)                                    计数

        变量名或者元素值 in 列表名                      是否在

        变量名或者元素值 not in 列表名                是否不在

删:

列表名.pop(索引)                                        删除指定索引位置的元素, 并返回被删除的元素

列表名.remove(元素)                                  删除指定元素, 删除第一个找到的元素

del 列表名[索引]                                         删除指定索引位置的元素

del 列表名                                                  从内存中删除整个列表, 相当于该列表从未定义

列表名.clear()                                            清空列表, 得到1个空列表, 类似于list1 = []

改:

列表名[索引] = 值                     

列表名.reverse()                                         反转列表元素内容

列表名.sort(key=None, reverse=False) 列表元素排序, key可以指定排序规则, 例如lambda word: len(word)按字符串长度排序/word[1]按字符串第2个元素排序, reverse表示升序还是降序, 默认是False(升序)

面试题:  append() 和 extend()的区别:

区别1: 参数要求不同.

        append(): 可以传入 任意变量.

        extend(): 必须传入 容器类型.

区别2: 作用不同.

        append(): 把元素追加到末尾, 默认是 当做1个整体 来添加的.

        extend(): 把容器类型的每个元素, 逐个添加进来, 底层有遍历的动作.

# 列表可以同时存储多个不同类型的值, 但是不推荐, 因为不好管理
list1 = [10, 20, 10.3, True, False, 'abc']
print(list1[0], list1[-1])                  # 10 abc
# 遍历列表
# 方式1: 直接获取列表的每个元素值
for i in range(len(list1)):
    print(i)
# 方式2: 通过索引的方式获取列表的元素值
# for循环
for i in range(len(list1)):
    print(list1[i])
# while循环
i = 0
while i < len(list1):
    print(list1[i])
    i += 1
# 列表的嵌套
list2 = [[10, 20, 30], [40, 50], [60, 70, 80, 90]]
# 索引
print(list2[0][1])                             # 20
# 切片, 对原列表不作改变
print(list2[0:2])                              # [[10, 20, 30], [40, 50]]
# 列表的增删改查
list3 = ['a', 'b', 'c']
# 增:
# append任意变量
list3.append(10)                               # ['a', 'b', 'c', 10]
# extend必须是容器变量
list3.extend('d')                              # ['a', 'b', 'c', 10, 'd']
# insert往指定位置的 前面 插入元素
list3.insert(-1, 'e')                  # ['a', 'b', 'c', 10, 'e', 'd']
# 查:
# index返回第一次出现的位置, 找不到就报错
print(list3.index(10))                          # 3
# count计数
print(list3.count('e'))                         # 3
# in是否在
print('q' in list3)                             # False
# not in是否不在
print(10 not in list3)                          # False
# 删:
# pop删除指定位置, 并返回删除的元素, 找不到就IndexError, 索引越界错误
print(list3.pop(3))                             # 10
# remove删除第一个找到的元素, 找不到就ValueError, 元素值不在列表中
list3.remove('e')                               # ['a', 'b', 'c', 'd']
# del删除索引位置的元素
del list3[0]                                    # ['b', 'c', 'd']
del(list3[0])                                   # ['c', 'd']
# clear清空列表, 得到一个空列表
list3.clear()                                   # []
# 改:
# 直接改
list3 = ['a', 'b', 'c']
list3[0] = 'd'                                  # ['d', 'b', 'c']
# reverse反转
list3.reverse()                                 # ['c', 'b', 'd']
# sort默认reverse为: False升序
list3.sort(reverse=True)                        # ['d', 'c', 'b']

7.3 元组

格式:

        uple1 = (值1, 值2, 值3...)

        tuple2 = tuple()

        tuple3 = ()

        tuple4 = (10, )    如果元组只有1个元素, 则该元素后必须加逗号

        tuple5 = (10)      如果不加逗号, 那就说明它就是1个该类型的变量 <class 'int'>

下标和切片:  支持

常用函数: index() count() len()

# 定义元组
tuple1 = (10, 20, 30, 40, 50)
# 切片, 切片后对原有元组不作修改
print(tuple1[2:4])                          # (30, 40)
# index第一次出现的位置, 找不到就报错ValueError
print(tuple1.index(20))                     # 1
# count计数
print(tuple1.count(10))                     # 1
# 元组嵌套列表
tuple2 = ([10, 20], [30, 40, 50], [60])
tuple2[0][1] = 1                            # ([10, 1], [30, 40, 50], [60])

7.4 字典

格式:

dict1 = {键:值, 键:值, ...}

dict2 = dict{}

dict3 = {}

特点: 键具有唯一性, 值可以重复

增/改: 字典名[键] = 值, 键存在就修改, 不存在就新增

删:  del clear()

查:  get(键名, 默认值)  keys()  values()  items()

# 定义字典
dict1 = {'name':'张三', 'age':23, 'gender':'male'}
dict2 = {10, 20, 30, 40}                  # 这个不是字典, 而是集合
print(dict2)                              # {40, 10, 20, 30}, 集合set内的元素排列顺序不固定
print(type(dict2))                        # <class 'set'>
# in, not in运算符, 只作用于键
print('张三' in dict1)                     # False
# 增
dict1['weight'] = 50
# 改
dict1['name'] = 'Jam'
# 删, 根据键删除该键值对, 不存在就报错
del dict1['name']
# 查, 根据键获取其对应的值, 如果不存在就返回默认值, 默认值不写则为None
print(dict1['gender'])                    # male, key访问, 字典[key]的方式获取值, 如果key不存在则报错
print(dict1.get('gender', 'male'))        # male, get方法访问, 不会报错
print(dict1.keys())                       # dict_keys(['age', 'gender', 'weight'])
print(dict1.values())                     # dict_values([23, 'male', 50])
print(dict1.items())                      # dict_items([('age', 23), ('gender', 'male'), ('weight', 50)])
# 遍历字典
# 方式1: 根据键 获取 对应的值
for key in dict1.keys():
    print(key, dict1.get(key))
# 方式2: 根据键值对 获取 键和值
for item in dict1.items():
    print(item[0], item[1])
# ==> 最终实际开发中, 加入拆包
for k, v in dict1.items():
    print(k, v)

练习题

# 练习题1:删除指定的元素
# 方法1: 根据索引删除, 正向遍历
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
i = 0
while i < len(words_list):
    if words_list[i] == 'cc':
        words_list.pop(i)
        # 走到这里, 说明已经删除了一个元素, 元素整体前移, 下标需要重新赋值
        i -= 1
    # 走到这里, 说明元素判断完毕, 无论是否删除, 都需要继续判断下个元素了
    i += 1
print(words_list)                       # ['bb', 'aa', 'dd']
# 方法2: 根据索引删除, 逆向遍历
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
i = len(words_list) - 1
while i >= 0:
    if words_list[i] == 'cc':
        words_list.pop(i)
    # 走到这里, 说明元素判断完毕, 无论是否删除, 都需要继续判断前个元素了
    i -= 1
print(words_list)                       # ['bb', 'aa', 'dd']
# 方法3: 列表推导式
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
words_list = [word for word in words_list if word != 'cc']
print(words_list)                       # ['bb', 'aa', 'dd']
# 方法4: 过滤器filter(过滤规则, 要操作的容器对象)
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
words_list =list(filter(lambda word: word != 'cc', words_list))
print(words_list)                       # ['bb', 'aa', 'dd']
# 方法5: 深浅拷贝: 列表名[::1] 底层会随着列表元素的变化而动态变化
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
for word in words_list[::1]:
    if word == 'cc':
        words_list.remove(word)
print(words_list)                       # ['bb', 'aa', 'dd']

# 练习题2: 统计每个字符出现的次数:    # 空间复杂度O(n2), 因为需要每次都对比一次
s = 'abfdjszgsruyzbfvkzsdureaig'
# 方式1: 遍历
char_count_dict = {}
for char in s:
    # 字典名.get(键, 默认值), 根据键获取对应的值, 如果没有该键, 赋默认值0
    # 对于每个字符, 对应的键的值都加1
    char_count_dict[char] = char_count_dict.get(char, 0) + 1
# 方式2: 字典推导式
char_count_dict = {char: s.count(char) for char in s}
# 打印结果
for k, v in char_count_dict.items():
    print(f'{k}({v})', end='')

# 练习题3: 统计大写小写数字字符的次数
s = 'zbdAS12354DFvHYjhe2546sbKD'
big_count, small_count, num_count = 0, 0, 0
for char in s:
    # 方式1: Python独有写法
    if 'A' <= char <= 'Z':
        big_count += 1
    if 'a' <= char <= 'z':
        small_count += 1
    if '0' <= char <= '9':
        num_count += 1
print(f'大写字母字符的个数为: {big_count}, 小写字母字符的个数为: {small_count}, 数字字符的个数为: {num_count}')

big_count, small_count, num_count = 0, 0, 0
for char in s:
    # 方式2: Python函数
    if char.isupper():
        big_count += 1
    if char.islower():
        small_count += 1
    if char.isdigit():
        num_count += 1
# 打印结果
print(f'大写字母字符的个数为: {big_count}, 小写字母字符的个数为: {small_count}, 数字字符的个数为: {num_count}')

# 练习题4: 约瑟夫环
"""
10个人围成一个圈, 从1开始数数字, 只要数到3或3的倍数, 就要被杀掉, 直至剩下最后一个人, 他的位置就是幸运数字
"""
num_list = [i for i in range(1, 11)]        # 生成位置序列
# 方式1: 循环
count = 0                                   # 表示每个人所数的数字
i = 0                                       # 表示每个人自己的位置
while len(num_list) != 1:
    # 每次循环, count加一, 判断是否为3的倍数
    count += 1
    if count % 3 == 0:
        num_list.pop(i)
        # 如果是3的倍数, 杀掉这个人之后, 每个人自己的位置向前移动1
        i -= 1
    # 判断完之后, 轮到下一个人判断
    i += 1
    # 如果本轮最后一个人的位置, 等于目前队伍的长度, 则重新赋值, 开始下一轮判断
    if i == len(num_list):
        i = 0
# 打印结果
print(f'幸运数字是: {num_list[0]}')

# 方式2: 公式完成
num_list = [i for i in range(1, 11)]        # 生成位置序列
i = 0
while len(num_list) != 1:
    i = (i + 2) % len(num_list)             # %取余, 两个人之后就是第三个人, 如果i超过队列长度, 取余获得下一个被杀的位置
    num_list.pop(i)
# 打印结果
print(f'幸运数字是: {num_list[0]}')

7.5 集合

格式: set1 = {值1, 值2, 值3...}

set2 = set()

set3 = {}

特点: 无序(元素的存 取顺序不一致), 唯一

应用场景: 去重

# 去重
list1 = ['aa', 'bb', 'cc', 'cc', 'cc', 'dd', 'bb', 'cc']
print(list(set(list1)))

关于包左包右

import random
print(random.randint(1, 2))               # 包左包右
print(list(range(1, 6)))                  # range(a, b)包左不包右
print('abcdefghijklmnopqrstuvw '[1:5])    # 包左不包右

8. 函数

概述: 函数也叫方法, Function(函数, 功能), Method(方法)表示, 函数 = 把具有独立功能的代码封装到一起, 使其成为具有特殊功能的代码集

抽取函数快捷键: ctrl + alt + m

好处: 提到代码的复用性, 模块化编程

格式:

        def 函数名(形参1, 形参2...):     # 函数名最好做到见名知意

                三引号 说明文档 三引号   # 函数的说明文档, 函数内部的第一行, 用三引号包裹

                函数体

                return 具体的返回值      # 作用1(主职): 结束函数的, 作用2(副职): 可以返回函数执行结果

调用格式: 写函数名(), 传入实参, 接收返回值

根据参数和返回值的不同, 主要分为四种写法: 无参无返回值, 有参无返回值, 无参有返回值, 有参有返回值

参数的分类:

        (1) 实参 位置参数, 实参和形参的个数, 对应的顺序(位置)都要相同

        (2) 实参 关键字参数, 必须通过形参名=值的形式传递实参, 实参和形参的个数必须保持一致, 对顺序无要求;         如果写实参的时候, 既有位置参数, 又有关键字参数, 则位置参数必须在关键字参数的前边, 关键字参数之间依旧没有顺序要求

        (3) 形参 普通参数, 即命名参数, 

        (4) 形参 缺省参数, 也叫默认参数, 作用于形参列表, 给形参赋一个初始值, 如果没有这个参数传递, 就用默认值;        形参列表中如果有缺省参数, 必须放在参数列表最后;        大致顺序: 普通参数 => 缺省参数 => 不定长参数

        (5) 形参 不定长参数(*args, **kwargs), *args, 可以接收任意多个位置参数, 并封装成元组; **kwargs, 可以接收任意多个关键字参数, 并封装成字典

形参是不可变类型, 形参的改变对实参没有任何影响

形参是可变类型, 形参的改变直接影响实参

当一个函数有返回值的时候, 这个函数可以作为参数传入另一个函数中

当一个函数返回多个值(返回1个结果), 会把多个值封装成1个元组进行返回

函数的嵌套调用: 指的是在一个函数中, 调用另一个函数, 根据入栈的顺序, 进行执行

细节: 函数的功能越单一越好, 最好1个函数只做1件事

变量的作用域: 指的是变量的作用范围, 即变量在哪里能用, 在哪里不能用

局部变量: 定义到函数的形参列表, 或者函数内的变量, 

生命周期: 随着函数的调用而存在, 函数的调用完毕而消失

全局变量: 定义到函数外的变量, 或者global修饰的变量, 在当前模块中的函数, 都可以使用, 

生命周期: 随着模块的加载而存在, 模块的卸载而消失

global: 被修饰的变量 => 全局变量, 可以实现定义在函数内的变量, 在函数外使用

匿名函数: 没有名字的函数, 也叫Lambda表达式 Lambda函数

格式: lambda 形参列表: 函数体

适用场景: 只适用于简单的业务场景, 函数体只有一行代码, 且有返回值的这种函数

# 演示 普通参数 + 缺省参数 + 不定长参数, 接收所有的位置参数 = 关键字参数
#             普通参数    缺省参数              不定长参数
def user_info(a, b, c=10, d=20, e='AI30期', *args, **kwargs):
    print(f'a: {a}, b: {b}, c: {c}, d: {d}, e: {e}') # a: 1, b: 2, c: 3, d: 4, e: 5
    print(f'args: {args}') # args: (6, 7, 8, 9)
    print(f'kwargs: {kwargs}') # kwargs: {'name': '李四', 'gender': '女'}
if __name__ == '__main__':
    user_info(1, 2, 3, 4, 5, 6, 7, 8, 9, name='李四', gender='女')

# 形参是不可变类型, 形参的改变对实参没有任何影响; 形参是可变类型, 形参的改变直接改变实参
def change1(a, b):
    a = 200
    b[1] = 1
if __name__ == '__main__':
    change1(100, [2, 3, 4])                     # 200 [2, 1, 4]

# 匿名函数
def get_sum(a, b):
    return a + b
if __name__ == '__main__':
    get_sum(10, 3)                              # 13
    get_sum1 = lambda a, b: a + b
    get_sum1(10, 3)                             # 13
# 匿名函数作为方法的实参进行传递
def my_calculate(a, b, func):
    return func(a, b)
if __name__ == '__main__':
    my_calculate(10, 3, lambda a, b: a * b)     # 30

练习题

# 练习题1: 扑克牌发牌
# 定义造牌函数
def buy_pokers():
    """
    定义造牌函数, 造出54张扑克牌
    :return: 扑克牌的字典, 以及对应的索引序列
    """
    poker_color = ['♠️', '♥️', '♦️', '♣️']
    poker_num = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2']
    poker = []
    for num in poker_num:
        for col in poker_color:
            col_num = col + num
            poker.append(col_num)
    poker.extend(['🃁', '🃏'])
    pokers = {item[0]:item[1] for item in enumerate(poker)}
    poker_list = list(pokers.keys())
    return pokers, poker_list
# 定义洗牌函数
def shuffle_poker_list(poker_list):
    """
    扑克牌进行洗牌, 即序列随机置换
    :param poker_list:进行随机置换的序列
    :return: 随机置换后的序列
    """
    import random
    random.shuffle(poker_list)
    return poker_list
if __name__ == '__main__':
    pokers, poker_list = buy_pokers()
    print(pokers)
    print(poker_list)
    poker_list = shuffle_poker_list(poker_list)
    print(poker_list)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值