Python基础 1.6 进阶与强化

1.6 进阶与强化

1.6.1 组包与拆包(重要)

1.组包

​ 把多个数据变成一个,实际上以前赋值的时候就可以直接学到,只是没提,在等号右边放置多个数据,就能自动包装成元组。

from_key = 2, 5, 7, 8, 9
print(from_key, type(from_key))
输出
(2, 5, 7, 8, 9) <class 'tuple'>

2.拆包

​ 相反地,如果左边变量数量是多个,则可以拆分右边对应容器的元素,但是谨记,变量数量必须等于元素数量,否则会报错,可以拆元组,列表,字典。

li = ["a", "b", "c", "d", 7]
a, b, c, d, e = li
print(a, b, c, d, e, type(a), type(e))
输出
a b c d 7 <class 'str'> <class 'int'>

上述为列表,元组拆分同理,但是字典略有不同,因为字典是键与键值对应的容器,如果用相同方法去拆分的话,拆出来的只有键。

dict01 = {"name": "tom", "age": 17, "sex": "female"}
a, b, c = dict01
print(a, b, c, type(a))
输出
name age sex <class 'str'>

如果想访问键值

print(a, dict01[a])
print(b, dict01[b])
print(c, dict01[c])
# 或者
for k, v in dict01.items():
    print(k, v)
# 实际上 k, v 这一步就是拆包了,本来 in dict.items()所获得的是多个元组,此步等于拆包了元组。

3 组包与拆包的应用

1.交换变量的值

一般情况下我们要交换变量,一般都需要用一个辅助变量。

a = 10
b = 20
c = 0
c = a
a = b
b = c
print(a,b)
# 输出
20,10

而利用组包拆包,我们只要一步,

a = 10
b = 20
a, b = b, a
print(a,b)
2. 函数可以返回多个数,亦可以直接分配给多个变量
def fun_pack(num1,num2,num3):
    num_sum = num1 + num2 + num3
    num_ave = num_sum/3
    return num_sum, num_ave


num_sum, num_ave = fun_pack(88, 98, 99)
print(num_sum, num_ave)

1.6.2 引用

1.引用

​ 给一个变量赋值的时候,我们就把一个数值所在的内存地址,引用给了变量。我们可以用id()这个函数来查看每个变量引用的数据的地址。

2.引用指向改变

​ 具体可以查看1.2变量和简单数据类型

3.函数传参是引用传递

def fun_id(num):
    print("函数调用的时候", id(num))


a = 10
print("函数调用前", id(a))
fun_id(a)
print("函数调用后", id(a))

输出

函数调用前 140708111845312
函数调用的时候 140708111845312
函数调用后 140708111845312

1.6.3 可变类型与不可变类型

​ 可变类型:在存储空间里可以直接修改的数据类型,在地址不变的情况下可以修改内容

  • 列表(list)
  • 字典(dict)
  • 集合(set)

​ 不可变类型:在存储空间里不可以直接修改的数据类型,在地址不变的情况下不可修改内容

  • 数值类型 int, bool, float
  • 字符串 str
  • 元组 tuple
li = [1, 2, 3, 4]
print("改变之前的地址", id(li))
li[0] = 5
print("改变之后的地址", id(li))
a = 5
print("改变之前的地址", id(a))
a = 6
print("改变之后的地址", id(a))
str_001 = "hello world"
print("改变之前的地址:", id(str_001))
str_001 = str_001.upper()
print("改变之后的地址:", id(str_001))

输出

改变之前的地址 2046831353408
改变之后的地址 2046831353408
改变之前的地址 140708111845152
改变之后的地址 140708111845184
改变之前的地址: 3060999261744
改变之后的地址: 3060999259760

可以看到 字符串和整数在经过所谓的修改,实际上已经引向了新的地址,并不是原来的地址了。

注意,可变类型的,传递进入函数的时候,我们引用的依旧是这个地址。

这个时候,只要我们不重新声明变量,此时引用的就是外面的全局变量,不用声明也可以对其进行更改,但是一旦只要进行了变量赋值,就会有所改变,此时函数里的变量会变成局部变量,不会影响到外面的变量指向的值。

def cha_dict(list_01):
    print(id(list_01))
    list_01 = [1, 2, 3, 4, 5, 6]
    print(id(list_01))
    return list_01


a = [1, 2, 3, 4]
print(id(a))
char_dict(a)
print(a)
cha_dict(a)
print(id(a))
print(a)
输出
1675900223552
1675900223552
1675900223552
[1, 2, 3, 4, 5]
1675900223552
1675899165760
1675900223552
[1, 2, 3, 4, 5]

,可以看出只要没进行重新赋值,我们通过函数可以直接改变可变类型的引向的值,地址不变。其他的可变类型与不可变类型同理。

def char_str(str_01):
    print(id(str_01))
    str_01 += "002"
    print(id(str_01))
    return str_01


def cha_str(str_01):
    print(id(str_01))
    str_01 = "001002"
    print(id(str_01))
    return str_01


a = "001"
print(id(a))
char_str(a)
print(a)
cha_str(a)
print(id(a))
print(a)

输出
2257338010608
2257338010608
2257338010928
001
2257338010608
2257338010544
2257338010608
001

可以看出,其实有个很好判断的认识,任何不可变变量,当你想要获得改变或者删除的内容的时候,我们都要重新使用赋值这个来引出结果,此时获得的就是新的地址,但是在函数里,确实会获得新地址,却也同时变成了局部变量。

1.6.4 列表推导式

​ 快速生成列表的表达形式,通过for添加元素的简洁写法。

类似切片,但是不能省略结束。

for in range(开始位置,结束位置,步长)

new_list = []
for i in range(5):
	new_list.append(i)

print(new_list)


new_list2 = [i for i in range(5)]
new_list3 = [i for i in range(101) if i % 2 ==0]
new_list3 = [i*2 for i in range(101) if i % 2 ==0]

格式
[i(可进行计算) for i in range(范围+步长) if 判断]

1.6.5 匿名函数

​ 匿名函数是简单函数的简洁写法,定义的函数没有名字。

lambda [形参1][形参2]````:[单行表达式] 或者函数调用

lambda主体是一个表达式,仅能在表达式里封装有限的逻辑,不能封装while,for循环。

lambda有自己的命名空间,且不能访问参数列表以外的参数。

lambda里不需要return,lambda自身表达式的结果就是函数返回结果,不可以不返回。如果想返回None得自己写None在表达式里。如果表达式里的函数没返回值的时候也是none

# 有参数有返回值的匿名函数,直接调用
ret = (lambda a, b: (a-b)*(a+b))(5, 4)
print(ret)

# 先给匿名函数命名再传参,有返回值
ave_grade = lambda chinese_grade, math_grade, english_grade: (chinese_grade + math_grade + english_grade) / 3
print("小明同学的考试平均分为:", ave_grade(98, 78, 100))
print("小花同学的考试平均分为:", ave_grade(95, 99, 90))

扩展

函数的参数是作为函数使用 匿名函数的应用

def foo(fn):
    fn()
    print(fn())


foo((lambda: 10 - 2))
# 可以看到foo函数的参数是函数,而我们此时可以快速的使用匿名函数进去被调用。

1.6.6 递归函数

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

递归函数一般会在特定情况下不在调用函数本身(防止内存溢出),会提前给你报错,超出最大递归深度。正常情况下一定要有一个可以出口的点。

1.用递归函数做一个阶乘

def fun_factorial(n):
    if n == 1:
        return 1
    else:
        ret = n * fun_factorial(n - 1)
        return ret


ret_10 = fun_factorial(10)
print("10的阶乘结果是:", ret_10)

输出

10的阶乘结果是: 3628800

1.6.7 enumerate del

1.enumerate

​ 通过配合for遍历容器的同时获取元素的索引位置,元素本身

user_list = [{'name': 'tom', 'age': 19, 'height': 1.78}, {'name': 'jerry', 'age': 25, 'height': 1.56}, {'name': 'john', 'age': 17, 'height': 1.90}]
i = 0
for user_dict in user_list:
    print(i, user_dict)
    i += 1
print("正常情况下我们要遍历出一个嵌套字典的列表里的所有内容")
i = 0
print("=="*20)
for i, user_dict in enumerate(user_list):
    print(i, user_dict)

上下俩段代码输出的内容是一致的

0 {'name': 'tom', 'age': 19, 'height': 1.78}
1 {'name': 'jerry', 'age': 25, 'height': 1.56}
2 {'name': 'john', 'age': 17, 'height': 1.9}
正常情况下我们要遍历出一个嵌套字典的列表里的所有内容
========================================
0 {'name': 'tom', 'age': 19, 'height': 1.78}
1 {'name': 'jerry', 'age': 25, 'height': 1.56}
2 {'name': 'john', 'age': 17, 'height': 1.9}

2. del

​ 删除列表里指定的元素,使用方法有俩种。

del 列表[索引] 
del(列表[索引])
del user_list[0]
print(user_list)

1.6.8 应用:学生名片管理系统(重要)

# 学生的列表应为全局变量,我们采用列表嵌套字典,用于保存用户信息
student_list = [{'name': 'Tom', 'age': 18, 'phone': '13824719558'}]


# 主界面应为一个死循环,因为必须一直停留在当前页面选择,以下为主界面逻辑
def main():
    while True:
        menu_print()
        user_select = int(input("请输入需要选择的功能:"))
        if user_select == 1:
            print("添加学生信息")
            add_student()
        elif user_select == 2:
            print("查询所有学生信息")
            check_all_student()
        elif user_select == 3:
            print("查询指定学生信息")
            check_student()
        elif user_select == 4:
            print("编辑指定学生信息")
            edit_student()
        elif user_select == 5:
            print("删除指定学生信息")
            delete_student()
        elif user_select == 6:
            print("退出学生名片管理系统")
            break
        else:
            print("输入错误,请重新输入")


# 显示主界面菜单,菜单是每次选择选项并且完全选项内容后会重复出现的东西,那么我们可以给写成函数来重复调用
def menu_print():
    print("=" * 10, "学生名片管理系统", "=" * 10)
    print("1.添加学生信息")
    print("2.查询所有学生信息")
    print("3.查询指定学生信息")
    print("4.修改指定学生信息")
    print("5.删除指定学生信息")
    print("6.退出系统")
    print("=" * 40)


'''
开始做第一个选项的函数,先分清逻辑顺序
首先我们要输入3个内容,名字,年龄,电话
然后用for循环遍历查看里面有没有名字冲突的,如果有则添加失败并且提醒,用break跳出循环
如果没有则进入else添加用户字典到列表里

'''


def add_student():
    new_name = input("请输入学生的名称:")
    new_age = int(input("请输入学生的年龄:"))
    new_phone = input("请输入学生的电话号码:")
    for a, student_dict in enumerate(student_list):
        if student_dict['name'] == new_name:
            print("该学生已经存在系统,无需再次添加")
            break
    else:
        new_student = {'name': new_name, 'age': new_age, 'phone': new_phone}
        student_list.append(new_student)
        print("添加学生信息成功")


'''
实现查询所有学生信息的功能
我们直接用之前学的enumerate直接遍历所有即可,如果为空则跳出循环
提示系统目前没有任何学生信息
'''


def check_all_student():
    if not student_list:
        print("系统目前没有任何学生信息,请先添加学生信息")
    else:
        print("序号\t\t姓名\t\t年龄\t\t电话")
        for n, student_dict in enumerate(student_list):
            print('%d\t\t%s\t\t%d\t\t%s' % (n+1, student_dict['name'], student_dict['age'], student_dict['phone']))


'''
实现查询指定学生的信息,
首先需要input来获取要查询学生的名字
然后遍历列表里的名字,如果没有则提示,有则显示内容
'''


def check_student():
    check_name = input("请输入要查询的学生名字:")
    for c, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此学生")
            print("学生信息如下\n")
            print("序号\t\t姓名\t\t年龄\t\t电话")
            print('%d\t\t%s\t\t%d\t\t%s' % (c + 1, student_dict['name'], student_dict['age'], student_dict['phone']))

            break
        else:
            print("学生档案里无此学生的相关信息,请重新确认")


'''
同样的,我们要实现修改指定学生的档案,也是要经过一次筛选,但是不用Break跳过循环,
而是重新输入数据进行更改
'''


def edit_student():
    check_name = input("请输入要修改的学生名字:")
    for e, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此学生")
            print("学生信息如下\n")
            print("序号\t\t姓名\t\t年龄\t\t电话")
            print('%d\t\t%s\t\t%d\t\t%s' % (e + 1, student_dict['name'], student_dict['age'], student_dict['phone']))
            edit_name = input("请输入要更改的学生名字:")
            edit_age = int(input("请输入要更改的学生年龄:"))
            edit_phone = input("请输入要更改的学生电话号码:")
            student_list[e] = {'name': edit_name, 'age': edit_age, 'phone': edit_phone}
            print("修改完成")
            break
    else:
        print("学生档案里无此学生的相关信息,请重新确认")


'''
删除指定的学生档案同理
'''


def delete_student():
    check_name = input("请输入要查询的学生名字:")
    for d, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此学生")
            print("学生信息如下\n")
            print("序号\t\t姓名\t\t年龄\t\t电话")
            print('%d\t\t%s\t\t%d\t\t%s' % (d + 1, student_dict['name'], student_dict['age'], student_dict['phone']))
            del student_list[d]
            print("已删除该学生的信息")
            break
        else:
            print("学生档案里无此学生的相关信息,请重新确认")


main()


# 字典输出问题,无法对齐提前打印的东西,格式化输出也不行,感觉需要一个表格才能限制,如果制表需要导入制表模块

下面是各项功能的测试

C:\Users\songs\AppData\Local\Programs\Python\Python38\python.exe "E:/Project/pythonProject/应用 学生管理系统.py"
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:1
添加学生信息
请输入学生的名称:Kitty
请输入学生的年龄:17
请输入学生的电话号码:13455977884
添加学生信息成功
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:2
查询所有学生信息
序号		姓名		年龄		电话
1		Tom		18		13824719558
2		Kitty		17		13455977884
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:3
查询指定学生信息
请输入要查询的学生名字:larry
学生档案里无此学生的相关信息,请重新确认
学生档案里无此学生的相关信息,请重新确认
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:3
查询指定学生信息
请输入要查询的学生名字:tom
学生档案里无此学生的相关信息,请重新确认
学生档案里无此学生的相关信息,请重新确认
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:3
查询指定学生信息
请输入要查询的学生名字:Tom
查到此学生
学生信息如下

序号		姓名		年龄		电话
1		Tom		18		13824719558
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:4
编辑指定学生信息
请输入要修改的学生名字:larry
学生档案里无此学生的相关信息,请重新确认
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:4
编辑指定学生信息
请输入要修改的学生名字:Kitty
查到此学生
学生信息如下

序号		姓名		年龄		电话
2		Kitty		17		13455977884
请输入要更改的学生名字:Kitty
请输入要更改的学生年龄:19
请输入要更改的学生电话号码:13459844657
修改完成
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:2
查询所有学生信息
序号		姓名		年龄		电话
1		Tom		18		13824719558
2		Kitty		19		13459844657
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:5
删除指定学生信息
请输入要查询的学生名字:larry
学生档案里无此学生的相关信息,请重新确认
学生档案里无此学生的相关信息,请重新确认
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:5
删除指定学生信息
请输入要查询的学生名字:Kitty
学生档案里无此学生的相关信息,请重新确认
查到此学生
学生信息如下

序号		姓名		年龄		电话
2		Kitty		19		13459844657
已删除该学生的信息
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:2
查询所有学生信息
序号		姓名		年龄		电话
1		Tom		18		13824719558
========== 学生名片管理系统 ==========
1.添加学生信息
2.查询所有学生信息
3.查询指定学生信息
4.修改指定学生信息
5.删除指定学生信息
6.退出系统
========================================
请输入需要选择的功能:6
退出学生名片管理系统

Process finished with exit code 0

我们做一个功能之前一定要先理清楚,主次逻辑,主逻辑我们要实现什么功能,实现完成再去分次选项的实现,再把此选项的再重新做进去主功能里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值