生成式、面向过程、与函数式

一、生成式

1、生成器

-.什么是生成器?
  生成的工具。
  生成器是一个 "自定义" 的迭代器, 本质上是一个迭代器。

-.如何实现生成器
  但凡在函数内部定义了的yield,
  调用函数时,函数体代码不会执行,
  会返回一个结果,该结果就是一个生成器。

1 # 自定义的迭代器
2 def func():
3     print('from func')
4     yield 'tank'
5 
6 
7 res = func()
8 # 当我们通过__next__取值时,才会执行函数体代码。
9 print(res.__next__())

2、yield

  每一次yield都会往生成器对象中添加一个值。
  - yield只能在函数内部定义
  - yield可以保存函数的暂停状态

有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但是不同于return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值

yield与return:
  相同点:
    返回值的个数都是无限制的。

  不同点:
    return只能返回一次值,yield可以返回多个值

 1 # 自定义的迭代器
 2 def func():
 3     print('开始准备下蛋')
 4     print('1---火鸡蛋1')
 5     yield '火鸡蛋1'
 6     print('2---火鸡蛋2')
 7     yield '火鸡蛋2'
 8     print('3---火鸡蛋3')
 9     yield '火鸡蛋3'
10 
11     print('取最后一个蛋,查看是否有')
12 
13 
14 # res是迭代器对象
15 res = func()
16 # 当我们通过__next__取值时,才会执行函数体代码。
17 # next(迭代器对象)
18 print(next(res))
19 print(next(res))
20 print(next(res))
21 
22 # 迭代器对象.__next__()
23 print(res.__next__())
24 print(res.__next__())
25 print(res.__next__())
26 print(res.__next__())  # StopIteration报错

自定义range功能,创建一个自定义的生成器

 1 # 自定义range功能,创建一个自定义的生成器
 2 # (1, 3)  # start--> 1  , end---> 5, move=2
 3 def my_range(start, end, move=1):  #
 4     while start < end:
 5         yield start
 6         start += move
 7 
 8 print(g_range)
 9 
10 for line in my_range(1, 5, 2):
11     print(line)

输出结果就是:1

       3

3、三元表达式

可以将if...else分支变成一行

语法:

  条件成立返回左边的值 if 判断条件 else 条件不成立返回右边的值

需求:比较两个值的大小,返回较大值

# 普通判断方法:if...else语法
def max1(num1, num2):
    if num1 > num2:
        return num1
    else:
        return num2
1 # 三元表达式:
2 def max2(num1, num2):
3     res = num1 if num1 > num2 else num2
4     print(res)
5 max2(100, 200)

需求:让用户输入用户名,输入的用户名不是以_str结尾,就为其后缀添加_str

1 def func():
2     name = input('>>>').strip()
3     name = name if name.endswith('_str') else name + '_str'
4     print(name)
5 func()

4、列表生成器

列表生成式:
  可以一行实现生成列表。
语法:
  list = [取出的每一个值、任意值 for 可迭代对象中取出的每一个值 in 可迭代对象]
  for的右边是循环次数,并且可以取出可迭代对象中每一个值
  for的左边可以为当前列表添加值
  list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象]

  list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象 if 判断]

 1 # 将list1中的值,依次取出,添加到new_list中
 2 list1 = [1, 2, 3, 4]
 3 # 普通方式
 4 new_list = []
 5 for i in list1:
 6     new_list.append(i)
 7 print(new_list)
 8 
 9 # 列表生成式
10 new_list = [i for i in list1]
11 print(new_list)

可以赋给任意值

list1 = ['st' for i in range(10)]
print(list1)
# 将name中每个人后缀都添加_str
name = ['zhansan', 'lisi', 'wangwu']
name_list = [line + '_str' for line in name]
print(name_list)

list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象 if 判断]

1 # 将name中的yang过滤掉,其他每个人后缀都添加_str
2 name = ['zhansan', 'lisi', 'wangwu','yang']
3 new_name = [line + '_str' for line in name if not line == 'yang']
4 print(new_name)

5、生成器表达式

生成器表达式(生成器生成式):
  - 列表生成式: 若数据量小时采用
    [line for line in range(1, 6)] ---> [1, 2, 3, 4, 5]
    优点:
      可以依赖于索引取值,取值方便

    缺点:
      浪费资源

  - 生成器生成式: 若数据量过大时采用
    () ---> 返回生成器
    (line for line in range(1, 6)) ---> g生成器(1, 2, 3, 4, 5)

    优点:
      节省资源

    缺点:
      取值不方便

方法类似于列表生成式,只是[]改成()

1 # 生成一个有1000个值的生成器
2 g = (line for line in range(1, 1000001))
3 # <generator object <genexpr> at 0x00000203262318E0>
4 print(g)
5 
6 # 列表生成式实现
7 list1 = [line for line in range(1, 1000001)]
8 print(list1)

二、面向过程编程

面向过程编程是一门编程思想。

面向过程编程:
  核心是 '过程' 二字,过程 指的是一种解决问题的步骤,即先干什么再干什么
  基于该编程思想编写程序,就好比在设计一条工厂流水线,一种机械式的思维方式。

  优点:
    将复杂的问题流程化,进而简单化

  缺点:
    若修改当前程序设计的某一部分, 会导致其他部分同时需要修改, 扩展性差。

  牵一发而动全身,扩展性差。

这里讲一个登录功能的实现

 1 # 1、校验密码合法性
 2 def get_user_psw():
 3     while True:
 4         username = input('输入用户名:').strip()
 5         # 效验用户输入是否为字母
 6         if username.isalpha():
 7             break
 8         else:
 9             print('输入不合法')
10 
11     while True:
12         password = input('输入密码:').strip()
13         re_password = input('请再次输入密码:').strip()
14         # 效验两次输入密码是否一致
15         if password == re_password:
16             break
17         else:
18             print('两次密码不一样')
19     return username, password
20 
21 
22 # 2、拼接字符串
23 def cut_user_pwd(username, password):
24     user_pwd_str = f'{username}:{password}\n'
25     return user_pwd_str
26 
27 
28 # 3、保存用户数据,写入文件
29 def save_date(user_pwd_str):
30     # 每个用户名写入一个文件中
31     with open('user_login.txt','a',encoding='utf-8')as f:
32         f.write(user_pwd_str)
33 
34 
35 # 注册功能
36 def register():
37     # 1、验证输入用户名与密码的合法性
38     username, password = get_user_psw()
39     # 2、拼接字符串
40     user_pwd_str = cut_user_pwd(username, password)
41     # 3、写入文件
42     save_date(user_pwd_str)
43 
44 
45 register()

现在需要修改一下功能,需要用户增加输入用户角色,则需要修改源代码

 1 # 需要修改一下功能,需要用户增加输入用户角色
 2 
 3 # 用户三种类别
 4 level = ['普通用户','管理员用户','超级用户']
 5 
 6 
 7 # 1、校验用户、密码合法性
 8 def get_user_psw():
 9     while True:
10         username = input('输入用户名:').strip()
11         # 效验用户输入是否为字母
12         if username.isalpha():
13             break
14         else:
15             print('输入不合法')
16 
17     while True:
18         password = input('输入密码:').strip()
19         re_password = input('请再次输入密码:').strip()
20         # 效验两次输入密码是否一致
21         if password == re_password:
22             break
23         else:
24             print('两次密码不一样')
25 
26     while True:
27         user_level = input('请输入用户等级:').strip()
28         # 保证用户输入的角色范围[普通用户、管理员用户、超级用户]
29         if user_level in level:
30             break
31         else:
32             print('输入有误')
33     return username, password, user_level
34 
35 
36 # 2.拼接字符串
37 def cut_user_pwd(username, password, user_level):
38     user_pwd_str = f'{username}:{password}:{user_level}\n'
39     return user_pwd_str
40 
41 
42 # 3.保存用户数据,写入文件中
43 # 每一个用户保存一个文件,以用户的名字当做文件名
44 def save_date(user_pwd_str, username):
45     with open(f'{username}.txt', 'w', encoding='utf-8')as f:
46         f.write(user_pwd_str)
47 
48 
49 # 注册功能
50 def register():
51     # 1、验证输入用户名与密码的合法性
52     username, password, user_level = get_user_psw()
53     # 2、拼接字符串
54     user_pwd_str = cut_user_pwd(username, password, user_level)
55     # 3、写入文件
56     save_date(user_pwd_str, username)
57 
58 
59 register()

三、匿名函数与内置函数

1、匿名函数:

无名字的函数

语法:

  lambda :
 冒号:左边是参数, 右边是返回值
因为没有名字,而函数的调用需要函数名+(),因而匿名函数需要一次性使用

注意: 匿名函数单独使用毫无意义,它必须配合 “内置函数” 一起使用的才有意义。

1 # 匿名(), return 已经自动添加了
2 # lambda 匿名(): return 1
3 func = lambda : 1
4 print(func())
5 func = lambda : 1
6 print()

2、内置函数

max求最大值

1 # max求最大值   max(可迭代对象)
2 list1 = [5, 1, 2, 3, 4]
3 
4 # max内部会将list1中的通过for取出每一个值,并且进行判断
5 print(max(list1))
 1 dict1 = {
 2     'a': 800,
 3     'b': 10,
 4     'c': 2000,
 5     'd': 110,
 6     'e': 150
 7 }
 8 # 字符串的比较: ASCII
 9 print(max(dict1))
10 # 
11 # # 获取value值最大的
12 print(max(dict1, key=lambda x:dict1[x]))

min求最小值

  print(min(dict1, key=lambda x:dict1[x]))

sorted: 默认升序(从小到大) reverse:反转 reverse默认是False

 

 1 dict1 = {
 2     'a': 800,
 3     'b': 10,
 4     'c': 2000,
 5     'd': 110,
 6     'e': 150
 7 }
 8 new_dict = sorted(dict1, key=lambda x:dict1[x])
 9 print(new_dict)
10 # reverse 反转
11 new_dict = sorted(dict1, key=lambda x: dict1[x], reverse=True)
12 print(new_dict)

 

 

 

posted @ 2019-11-14 17:01  treeter  阅读(241)  评论(0编辑  收藏  举报