2021-09-27大数据学习日志——Python基础——强化和进阶(附练习题)

学习目标:

  1. 能够掌握组包和拆包的使用,例如:交换两个变量的值,函数同时返回多个值
  2. 知道可变类型与不可变类型有哪些
  3. 能够通过for和range配合控制循环范围
  4. 能够使用列表推导式创建包含1-100之间元素的列表
  5. 能够通过匿名函数编写简单的函数
  6. 了解函数递归的调用流程
  7. 能够完成学生名片管理系统案例:增、删、改、查

01_组包和拆包

学习目标:

  • 能够掌握组包和拆包的使用,例如:交换两个变量的值,函数同时返回多个值

1.1 组包

  • = 右边有多个数据时, 会自动包装为元组
# 组包,1, 2, 3封装成元组再赋值,多变一
result = 10, 20, 30
print(result, type(result))  # (10, 20, 30) <class 'tuple'>

1.2 拆包

  • 如果 变量数量 = 容器长度, 容器中的元素会一一对应赋值给变量
  • 拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常
  • 除了对元组拆包之外,还可以对列表、字典等拆包
# 拆包,一变多
a, b, c = (10, 20, 30)
print(a)  # 10
print(b)  # 20
print(c)  # 30

1.3 应用场景

1.3.1 交换变量的值

a = 10
b = 20
a, b = b, a  # 先自动组包,后自动解包(拆包)

1.3.2 函数可以同时返回多个数

# 函数可以同时返回多个数
def return_arg():
    return 1, 2, 3


# 函数调用
# 变量名 = 函数()
ret = return_arg()
print(ret)

# 返回值直接做拆包
r1, r2, r3 = return_arg()
print(r1, r2, r3)

1.3.3 字典元素拆包

info_dict = {'name': 'mike', 'age': 34}

# 遍历字典,取出每一个item
for temp in info_dict.items():
    print(temp)     # 元组:(key, value)
    key, value = temp   # 元组拆包
    print(key, value)

02_引用

学习目标:

  • 知道引用是别名的意思
  • 能够使用id函数获取变量的地址

2.1 引用

  • 引用:是一个变量或值的另一个名字,又称别名
    • 赋值本质:给右边的变量或值,起一个别名
  • 可以使用 id函数 查看变量的引用地址,引用地址相等,说明指向同一个内存空间
    • 每一次运行程序,每次地址都可能不一样
# a 是 10 的引用,10的别名是a,操作a就是操作10
a = 10
print(id(a), id(10))  # 地址id一样,指向同一个内存空间

2.2 引用指向改变

# a 是 10 的引用,10的别名是a,操作a就是操作10
a = 10
print(id(a), id(10))  # 地址id一样,指向同一个内存空间

# b 是 a 的引用,b的别名是a,操作a就是操作b
b = a
print(id(b), id(a))  # 地址id一样,指向同一个内存空间
print(a, b)  # 10 10

# b 是 20 的引用,20的别名是b,操作b就是操作20
# b已经和上面的a没有关系,现在是20的别名
b = 20
print(b, id(b)) # 和a的地址不一样了,说明b和a没有关系

2.3 函数传参是引用传递

  • 函数传参是引用传递
# 给函数传参是引用传递
# 带参数函数定义
def func(num):
    print('func = ', id(num))


# 给函数传参,变量传参
a = 10
print('func调用前 = ', id(a))
func(a)
print('func调用后 = ', id(a))

运行结果:

func调用前 =  4404906944
func =  4404906944
func调用后 =  4404906944

03_可变类型与不可变类型

学习目标:

  • 知道可变类型与不可变类型有哪些

3.1 可变类型和不可变类型

  • 可变类型: 在存储空间中可以直接修改的数据类型

    • 列表 list
    • 字典 dict
    • 集合set
  • 不可变类型: 在存储空间中不可以直接修改的数据类型

    • 数值类型 int, bool, float
    • 字符串 str
    • 元组 tuple
"""
可变类型: 列表、字典、集合
不可变类型: 数字类型(int, bool, float)、字符串、元组
可变类型:在地址不变的情况下,可以修改内容
不可变类型: 在地址不变的情况下,不可修改内容
"""

# 验证列表是可变类型
my_list = ['a', 'b']
print('改之前的地址:', id(my_list))

my_list.append('c')  # 追加元素
print('改之后的地址:', id(my_list))  # 地址和改之前一样
print(my_list)  # ['a', 'b', 'c']

print('=' * 20)

# 验证int是不可变类型
a = 10
print('改之前的地址:', id(a))

a = 20  # a是20的别名,重新指向新的空间,和前面的a没有关系,不是改前面的内容
print('改之后的地址:', id(a))  # 和改之前地址不一样了
print(a)  # 20

04_range

学习目标:

  • 能够通过for和range配合控制循环范围

4.1 range的使用

  • range() 方法可创建一个整数列表对象,一般用在 for 循环中
    • range(开始位置, 结束位置,步长)
      • 和切片用法差不多
# 1. 打印:0、1、2、3、4
# for i in range(5):  # [0, 5)
for i in range(0, 5):  # [0, 5)
    print(i)

# 2. 1~100的累加
# 2.1 定义辅助变量
_sum = 0

# 2.2 for 控制循环范围
for i in range(1, 101):
    # 2.3 累加
    _sum += i

# 2.4 在循环外面打印累加结果
print(_sum)

# 3. 验证步长,打印:0、2、4
for i in range(0, 5, 2):  # [0, 5)
    print(i)

05_列表推导式

学习目标:

  • 能够使用列表推导式创建包含1-100之间元素的列表

5.1 列表推导式

  • 列表推导式:快速生成列表元素的表达形式,通过for添加列表元素的简洁写法
  • 推导式基本格式: [计算公式 for 循环 if 判断]
  • 特点:
    • 每循环一次,将计算公式的结果添加到列表中
    • 计算公式可以使用遍历出的数据
    • for 遍历出的数据 必须满足 if 判断 才会使用计算公式生成元素
# 普通方法:遍历0~4范围的元素,这些元素添加到列表中
# 1. 空列表
new_list = []

# 2. range(5)遍历取数
for i in range(5):
    # 2.1 取出来的元素追加到列表
    new_list.append(i)

# 3. 循环外面,打印结果
print(new_list)

print('='*30)

# 通过列表推导式,实现上面的效果 [计算公式 for循环体]
# 1. for i in range(5), 取出0,放在i变量中,i追加到列表
# 2. 循环下一步,取出2,放在i变量中,i追加到列表
# 重复,直到退出循环
new_list2 = [i for i in range(5)]
print(new_list2)

print('='*30)


# 0~10之间数,偶数才添加到列表
# 普通方法实现
# 1. 空列表
new_list = []

# 2. range(11)遍历取数
for i in range(11):
    # 2.1 取出来的元素是偶数的话,追加到列表
    # 2.2 i % 2 == 0, i 对 2求余,结果为0,就是偶数
    if i % 2 == 0:
        new_list.append(i)

# 3. 循环外面,打印结果
print(new_list)

print('='*30)

# 列表推导式实现
# [i for i in range(11) if i % 2 == 0]
# 1. for i in range(11)取第一个元素
# 2. if i % 2 == 0
# 3. 上面满足条件的i, 条件到列表
new_list2 = [i for i in range(11) if i % 2 == 0]
print(new_list2)

运行结果:

[0, 1, 2, 3, 4]
==============================
[0, 1, 2, 3, 4]
==============================
[0, 2, 4, 6, 8, 10]
==============================
[0, 2, 4, 6, 8, 10]

06_匿名函数

学习目标:

  • 能够通过匿名函数编写简单的函数

  • 匿名函数是简单普通函数的简洁写法
  • 定义的函数没有名字,这样的函数叫做匿名函数
  • 匿名函数的语法结构:
lambda [形参1], [形参2], ... : [单行表达式] 或 [函数调用]
  • 示例代码:
# 无参有返回值匿名函数
# a) 匿名函数整体就是函数名字, 函数名字()就是函数调用
ret = (lambda: 1 + 1)()
print(ret)
# b) 给匿名函数起一个函数名字,函数名字()就是调用函数
func = lambda: 1 + 1  # 给匿名函数起一个函数名字叫func
ret = func()  # 返回值变量 = 函数名()
print(ret)

print('=' * 30)

# 有参有返回值匿名函数
# a. 直接调用匿名函数
ret = (lambda a, b: a - b)(30, 10)
print(ret)

# b. 先给匿名函数起名,再调用
func = lambda a, b: a - b
ret = func(30, 10)
print(ret)
  • 匿名函数中不能使用 while 循环、for 循环,只能编写单行的表达式,或函数调用

  • 匿名函数中返回结果不需要使用 return,表达式的运行结果就是返回结果

  • 匿名函数中也可以不返回结果。例如: lambda : print('hello world')

07_递归函数

学习目标:

  • 了解函数递归的调用流程

7.1 什么是递归函数

  • 如果 一个函数在内部调用其本身,这个函数就是 递归函数

  • 递归函数一般会在特定情况下不再调用函数本身(一定要有出口),否则会导致到达最大递归次数, 程序报错

7.2 通过递归函数实现阶乘

阶乘的规律:

1! = 1  
2! = 2 × 1 = 2 × 1!  
3! = 3 × 2 × 1 = 3 × 2!  
4! = 4 × 3 × 2 × 1 = 4 × 3!  
...  
n! = n × (n-1)!

示例代码:

# 1. 定义函数(参数)
def func(n):
    # 2. 如果我是 1 ,直接返回 1
    if n == 1:
        return 1
    # 3. 否则,返回 n * 函数调用自己(n-1)
    else:
        ret = n * func(n-1)
        return ret


# 函数调用
_ret = func(3)
print(_ret)

调用流程:

08_enumerate、del

学习目标:

  1. 能够通过 for 配合 enumerate 遍历容器同时获取元素索引位置、元素
  2. 能够通过del删除列表元素

8.1 enumerate 的使用

  • 通过 for 配合 enumerate 遍历容器同时获取元素索引位置、元素

示例代码:

user_list = [{'name': 'mike', 'age': 34, 'tel': '110'},
             {'name': 'yoyo', 'age': 18, 'tel': '120'}]

# 遍历列表,同时把索引位置能打印
# 普通方法实现
# 1. 定义索引位置变量
i = 0
# 2. for遍历列表,打印:索引、元素
for user_dict in user_list:
    print(i, user_dict)
    # 3. 索引位置+1
    i += 1

print('=='*20)

# 通过enumerate方法实现
# enumerate(容器变量):获取到:元素位置,元素
for i, user_dict in enumerate(user_list):
    print(i, user_dict)

运行结果:

0 {'name': 'mike', 'age': 34, 'tel': '110'}
1 {'name': 'yoyo', 'age': 18, 'tel': '120'}
========================================
0 {'name': 'mike', 'age': 34, 'tel': '110'}
1 {'name': 'yoyo', 'age': 18, 'tel': '120'}

8.2 通过del删除列表元素

  • 通过del删除列表元素:del 列表[索引]

示例代码:

user_list = [{'name': 'mike', 'age': 34, 'tel': '110'},
             {'name': 'yoyo', 'age': 18, 'tel': '120'}]

# 通过del删除列表元素 del 列表[索引位置]
print(user_list)    # [{'name': 'mike', 'age': 34, 'tel': '110'}, {'name': 'yoyo', 'age': 18, 'tel': '120'}]

# 删除索引位置为0的元素
del user_list[0]

print(user_list) # [{'name': 'yoyo', 'age': 18, 'tel': '120'}]

09_学生名片管理系统

学习目标:

  • 能够完成学生名片管理系统案例:增、删、改、查

示例代码:

# 0. 函数的外面,定义一个全局变量(列表),用于保存用户信息
user_list = [{'name': 'mike', 'age': 34, 'tel': '110'},
             {'name': 'yoyo', 'age': 18, 'tel': '120'}]


# 显示菜单函数定义
def show_menu():
    print('=' * 20)
    print('= 1. 添加学生')
    print('= 2. 查询所有学生')
    print('= 3. 查询某个学生')
    print('= 4. 修改某个学生')
    print('= 5. 删除某个学生')
    print('= 6. 退出系统')
    print('=' * 20)


# 定义新建学生的函数
def add_stu_info():
    """添加学生信息"""
    # 1. 输入用户信息:姓名、年龄、电话
    _name = input('请输入学生姓名:')
    _age = int(input('请输入学生年龄:'))  # 年龄应该是整型,所有做了int转换
    _tel = input('请输入学生电话:')

    # 2. 通过for遍历,取出某个元素后,这个元素就是字典
    for user_dict in user_list:
        # 2.1 字典[‘name’] == 用户输入的名字,是否相等,相等则跳出循环
        if user_dict['name'] == _name:
            print('此用户已经存在,请重来')
            # 2.2 break跳出循环
            break
    else:
        # 3. for中的else 如果用户不存在列表中,添加用户字典到列表
        # 3.1 创建字典
        info_dict = {'name': _name, 'age': _age, 'tel': _tel}

        # 3.2 追加列表
        # user_list是可变类型,没有重新赋值,没有改变原来地址,所以不用global声明
        user_list.append(info_dict)


# 显示所有的学生,带序号的
def show_all_stu():
    """显示所有的学生"""
    # 1. 遍历前,打印一些提示信息:序号    姓名  年龄  电话
    # \t一个tab键的空格
    print('序号\t\t姓名\t\t年龄\t\t电话')

    # 2. 遍历 for 索引位置,字典 in enumerate(user_list):
    for i, user_dict in enumerate(user_list):
        # 2.1 打印一个用户的信息 索引位置+1,user_dict[‘name’]……
        print('%d\t\t%s\t\t%d\t\t%s' % (i + 1, user_dict['name'], user_dict['age'], user_dict['tel']))


# 显示某个学生
def show_one_stu():
    """显示某个学生"""
    # 1. 输入姓名
    _name = input('请输入学生姓名:')

    # 2. 通过for遍历,取出一个字典user_dict
    for user_dict in user_list:
        # 2.1 user_dict[‘name’]和输入姓名判断
        if user_dict['name'] == _name:
            # 2.1.1 如果相等,输出用户信息,退出循环
            print('查询到的用户信息如下:')
            print('%s\t%d\t%s' % (user_dict['name'], user_dict['age'], user_dict['tel']))
            break
    # 3. for中的else,循环执行完毕,没有break,说明用户不存在,提示一下
    else:
        print('查询的用户不存在')


def update_stu_by_name():
    """更新某个学生信息,根据输入的姓名匹配哪个学生"""
    # 1. 输入需要修改的用户姓名
    update_name = input('输入需要修改的用户姓名:')

    # 2. for遍历,带索引的遍历   i, user_dict  in user_list
    for i, user_dict in enumerate(user_list):
        # 2.1 如果user_dict['name']和输入用户名字相等
        if user_dict['name'] == update_name:
            # 2.1.1 重新输入新的姓名、年龄、电话
            _name = input('请输入新的学生姓名:')
            _age = int(input('请输入新的学生年龄:'))
            _tel = input('请输入新的学生电话:')
            # 2.1.2 对user_list[i]['name'] = 新的name
            user_list[i]['name'] = _name
            user_list[i]['age'] = _age
            user_list[i]['tel'] = _tel
            # 2.1.3 ……、修改成功打印、break跳出循环
            print('修改成功')
            break
    # 3. for中的else 输入的用户不在列表
    else:
        print('输入的用户不在列表,请重新输入')


def del_stu_by_name():
    """删除某个学生,根据输入的姓名"""
    # 1. 输入用户姓名
    _name = input('请输入需要删除的名字:')

    # 2. for遍历,带索引的遍历   i, user_dict
    for i, user_dict in enumerate(user_list):
        # 2.1 如果user_dict['name']和输入用户名字相等
        if user_dict['name'] == _name:
            # 2.1.1 del 列表[i], 同时break跳出循环
            del user_list[i]
            print('删除成功')
            break
    # 3. for中else 输入的用户在列表中,不存在
    else:
        print('用户不在列表中,无法删除')


# 写一个主程序
def main():
    # 1. 死循环
    while True:
        # 调用菜单
        show_menu()

        # 2. 用户输入数字
        cmd = input("请输入功能数字:")

        # 3. 条件选择
        if cmd == "1":
            # print('添加学生')
            add_stu_info()
            # print(user_list) # 打印列表,做测试,看数据
        elif cmd == "2":
            # print('查询所有学生')
            show_all_stu()

        elif cmd == "3":
            # print('查询某个学生')
            show_one_stu()

        elif cmd == "4":
            # print('修改某个学生')
            update_stu_by_name()
        elif cmd == "5":
            # print('删除某个学生')
            del_stu_by_name()
        elif cmd == "6":
            print('退出循环')
            break
        else:
            print('输入有误,请重新输入')


# 调用主程序
main()

强化和进阶——练习题

能力目标:

  • 能够对元组进行拆包
  • 知道列表、字典是Python中常见的可变类型
  • 知道数字、字符串、元素是Python中常见的不可变类型
  • 知道使用列表推导式能够创建包含1-100之间元素的列表
  • 知道新建名片功能的实现思路
  • 知道显示全部名片功能的实现思路
  • 知道查询名片功能的实现思路
  • 知道修改名片功能的实现思路
  • 知道删除名片功能的实现思路

关卡一:基础题

1. 什么是组包?什么是拆包?

参考答案

组包: =右边有多个数据时, 会自动包装为元组
拆包: =如果 变量数量 = 容器长度, 容器中的元素会一一对应赋值给变量

2. 什么是可变类型?可变类型有哪些?什么是不可变类型?不可变类型有哪些?

参考答案

可变类型: 在地址不变的情况下,可以修改内容  `
    
列表 list
字典 dict
集合 set
​
不可变类型: 在地址不变的情况下,不可修改内容
  
数值类型 int, bool, float
字符串 str
元组 tuple

3. Python中使用什么函数来查看变量的内存地址?

参考答案

id函数

4. 什么是列表推导式?格式是什么样的?有什么特点?

参考答案

列表推导式: 快速生成列表元素的表达形式
推导式基本格式: [计算公式 for循环 if判断]
    
特点:
    每循环一次,将计算公式的结果添加到列表中
    计算公式可以使用遍历出的数据
    for遍历出的数据 必须满足if判断 才会使用计算公式生成元素

5. 定义匿名函数的格式是什么?

参考答案

lambda 形参列表:计算表达式

6. 什么是递归函数?

参考答案

一个函数在内部调用其本身,这个函数就是 递归函数。

关卡二:综合题

1. 设计一个程序

已知列表num, 完成列表num的去重,并使用一行代码完成num列表奇数的筛选

num = [1,1,2,3,4,4,5]

训练提示

set类型可以完成列表的去重,列表推导式可以一行代码完成奇数筛选

参考答案

num = list(set(num))
num = [i for i in num if i % 2 != 0]

2. 设计一个程序

  • 用列表推导式求出100以内4的倍数:

参考答案

list1 = [i for i in range(1, 100) if i % 4 == 0]
print(list1)

3. 设计一个程序:

  • 实现名片管理系统代码至少2遍,直到自己能根据运行效果,就能写出完整的程序代码

关卡三:扩展题

1. 设计一个程序

  • 输出 9*9 乘法口诀表

    提示:

    1. 使用for循环嵌套,分行与列考虑,共9行9列,i控制行,j控制列

    2. 使用range函数

1*1=1  
2*1=2  2*2=4  
3*1=3  3*2=6  3*3=9  
4*1=4  4*2=8  4*3=12  4*4=16  
5*1=5  5*2=10  5*3=15  5*4=20  5*5=25  
6*1=6  6*2=12  6*3=18  6*4=24  6*5=30  6*6=36  
7*1=7  7*2=14  7*3=21  7*4=28  7*5=35  7*6=42  7*7=49  
8*1=8  8*2=16  8*3=24  8*4=32  8*5=40  8*6=48  8*7=56  8*8=64  
9*1=9  9*2=18  9*3=27  9*4=36  9*5=45  9*6=54  9*7=63  9*8=72  9*9=81  

参考答案

# i控制行
for i in range(1, 10):
    # j控制列
    for j in range(1, i+1):
        print("%d*%d=%d  " % (i, j, i*j), end="")
    print()

2. 自行探究下面代码(偏难)

  • 注意1: 本题要结合函数的使用, 以及引用的概念, 综合来看下面的代码. 看不懂没关系,到时候听讲解

  • 注意2: 本题和第三题有关联关系. 如果看不懂的, 就暂时不用做第三题, 直接查看答案了解思路就行.

# 在PyCharm中拷贝下面代码, 尝试读懂下面的写法
# 思考: 为什么使用do函数中的action(), 但是调用了eat函数
​
# 1. 函数名, 其实也是一个变量, 也会有id地址
def eat():
    print(id(eat), "吃东西")
  
  
def drink():
    print(id(drink), "喝东西")
  
  
# 2. 只要是变量, 就可以传参, 因此, 函数名可以当做参数传递
def do(action):
    # 3. 只要id相同, 就说明是同一个函数
    print(id(action))
    # 4. 函数名+()就是函数调用
    action()
    
    
# 5. 想调用哪个函数, 就传递函数名. 
do(eat)  # 这样的写法有助于扩充程序功能. 增加了其他方法后, 调用方法不用变

3. 设计一个程序(偏难)

  • 根据第二题的探究结果, 结合匿名函数, 实现下面需求

  • 使用匿名函数,实现调用一个函数处理加减乘除。(不需要考虑被除数为 0 的情况。)

    • 定义四个匿名函数实现加、减、乘、除运算

    • 定义一个函数接收 两个数字 和 匿名函数,并使用匿名函数来处理两个数字

    • 在函数中调用匿名函数,输出运算结果

    提示:

    1. 函数的参数是可以传入另一个函数名的

    2. 每个运算定义一个匿名函数: add = lambda x, y: x + y**

    3. 定义一个函数接收匿名函数, 并在该函数内实现匿名函数的调用:

参考答案

def compute(a, b, command):
    res = command(a, b)
    print(res)
​
add = lambda x, y: x + y
minus = lambda x, y: x - y
mul = lambda x, y: x * y
div = lambda x, y: x / y
​
compute(11, 22, add)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值