Python 基础入门笔记(三)———— 公共操作、推导式、函数、lambda表达式、高阶函数

文章目录

  • 一、公共操作
    • 1.1 运算符
    • 1.2 公共方法
    • 1.3 容器类型转换
  • 二、推导式
    • 2.1 列表推导式
    • 2.2 字典推导式
    • 2.3 集合推导式
  • 三、函数
    • 3.1 函数的定义
    • 3.2 函数的说明文档
    • 3.3 变量的作用域
    • 3.4 函数的返回值
    • 3.5 函数的参数
      • 3.5.1 位置参数
      • 3.5.2 关键字参数
      • 3.5.3 缺省参数(默认参数)
      • 3.5.4 不定长参数(可变参数)
    • 3.6 拆包和交换变量值
      • 3.6.1 拆包
      • 3.6.2 交换变量值
    • 3.7 引用
      • 3.7.1 了解引用
      • 3.7.2 引用当实参
    • 3.8 递归
  • 四、lambda表达式
    • 4.1 lambda表达式语法
    • 4.2 lambda表达式的参数
      • 4.2.1 无参数
      • 4.2.2 有参数
      • 4.2.3 默认参数
      • 4.2.4 可变参数
    • 4.3 lambda表达式的应用
      • 4.3.1 带判断的lambda
      • 4.3.2 列表数据按字典key的值排序
  • 五、高阶函数
    • 5.1 高阶函数示例
    • 5.2 内置高阶函数
      • 5.2.1 map()
      • 5.2.2 reduce()
      • 5.2.3 filter()


一、公共操作

1.1 运算符

运算符 描述 支持的容器类型
+ 合并 字符串、列表、元组
* 复制 字符串、列表、元组
in 元素是否存在 字符串、列表、元组、字典
not in 元素是否不存在 字符串、列表、元组、字典
# 合并
str1 = 'aa'
str2 = 'bb'
list1 = [1, 2]
list2 = [10, 20]
t1 = (1, 2)
t2 = (10, 20)
# 1. 字符串
print(str1+str2)  # aabb
# 2. 列表
print(list1 + list2)  # [1, 2, 10, 20]
# 3. 元组
print(t1 + t2)  # (1, 2, 10, 20)


# 复制
str1 = 'a'
list1 = ['hello']
t1 = ('hello',)
# 1. 字符串
print(str1 * 5)  # aaaaa
# 2. 列表
print(list1 * 5)  # ['hello', 'hello', 'hello', 'hello', 'hello']
# 3. 元组
print(t1*5)  # ('hello', 'hello', 'hello', 'hello', 'hello')


# 元素是否存在
str1 = 'abcd'
list1 = [10, 20, 30, 40]
t1 = (100, 200, 300, 400)
dict1 = {'name': 'Python', 'age ': 30}
# 1. 字符
print('a' in str1)  # True
print('a' not in str1)  # False
# 2. 列表
print(10 in list1)  # True
print(10 not in list1)  # False
# 3. 元组
print(10 in t1)  # False
print(10 not in t1)  # True
# 4. 字典
print('name' in dict1)  # True
print('name' not in dict1)  # False
print('name' in dict1.keys())  # True
print('name' in dict1.values())  # False

1.2 公共方法

函数 描述
len() 计算容器中元素个数
del 或 del() 删除
max() 返回容器中元素最大值
min() 返回容器中元素最小值
range(start, end, step) 生成从 start 到 end 的数字(不包括 end),步长为 step,供 for 循环使用
enumerate() 函数用于将一个可遍历的数据对象(如:列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

测试数据如下:

str1 = 'abcd'
list1 = [10, 20, 30, 40]
t1 = (10, 20, 30, 40)
s1 = {10, 20, 30, 40}
dict1 = {'name': 'Python', 'age ': 30}

len():

print(len(str1))  # 4
print(len(list1))  # 4
print(len(t1))  # 4
print(len(s1))  # 4
print(len(dict1))  # 2

del 或 del():

del str1  # 删除字符串str1
# print(str1)  # 报错

# del list1 # 删除列表list1
# print(list1) # 报错
del(list1[0])  # 删除 10
print(list1)  # [20, 30, 40]

max() 和 min():

print(max(str1))  # d
print(max(list1))  # 40

range(start, end, step):

'''
# 1. 如果不写开始,默认从 0 开始
# 2. 如果不写步长,默认步长为 1
'''
print(range(1, 10, 1))  # range(1, 10) 可迭代对象
for i in range(1, 10, 1):
    print(i)  # 循环打印 1-9

for i in range(1, 10):
    print(i)  # 循环打印 1-9

for i in range(10):
    print(i)  # 循环打印 0-9

enumerate():

list1 = ['a', 'b', 'c', 'd', 'e']
# enumerate 返回结果是元组,元组第一个数据是原迭代对象的数据对应的下标,元组第二个数据是原迭代对象的数据
for i in enumerate(list1):
    print(i)  # (0, 'a') (1, 'b') (2, 'c') (3, 'd') (4, 'e')

# 设置对应下标的起始值
for i in enumerate(list1, start=1):
    print(i)  # (1, 'a') (2, 'b') (3, 'c') (4, 'd') (5, 'e')

for index, char in enumerate(list1, start=1):
    print(f'下标是{index}, 对应的字符是{char}')  # 下标是1, 对应的字符是a   下标是2, 对应的字符是b  ...

1.3 容器类型转换

函数 描述
tuple() 转换成元组
list() 转换成列表
set() 转换成集合
list1 = [10, 20, 30, 40, 20, 50]
t1 = (10, 20, 30, 40)
s1 = {10, 20, 30, 40}

# tuple():转换成元组
print(tuple(list1))  # (10, 20, 30, 40, 20, 50)
print(tuple(s1))  # (40, 10, 20, 30)

# list():转换成列表
print(list(t1))  # [10, 20, 30, 40]
print(list(s1))  # [40, 10, 20, 30]

# set():转换成集合
# 集合可以快速完成列表去重
print(set(list1))  # {40, 10, 50, 20, 30}
print(set(t1))  # {40, 10, 20, 30}

二、推导式

推导式作用: 简化代码
只有列表、字典、集合有推导式。

2.1 列表推导式

作用:用一个表达式创建一个有规律的列表或控制一个有规律的列表。

  1. 一般列表推导式

    # 需求:创建一个 0-10 的列表。
    # for 循环
    list1 = []
    for i in range(10):
        list1.append(i)
    print(list1)
    
    # 列表推导式实现
    list1 = [i for i in range(10)]
    print(list1)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
  2. 带 if 的列表推导式

    # 需求:创建0-10的偶数列表
    
    # 法一:
    list1 = [i for i in range(0, 10, 2)]
    print(list1)  # [0, 2, 4, 6, 8]
    
    # 法二:带 if 的列表推导式
    list1 = [i for i in range(10) if i % 2 == 0]
    print(list1)  # [0, 2, 4, 6, 8]
    
  3. 多个 for 循环实现列表推导式

    # 需求:创建 [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
    # 法一:
    list1 = []
    # for i in range(1, 3):
    #     for j in range(3):
    #         list1.append((i, j))
    
    # 法二:多个 for 循环实现列表推导式
    list1 = [(i, j) for i in range(1, 3) for j in range(3)]
    print(list1)
    

2.2 字典推导式

  1. 创建一个字典:字典 key 是 1-5 数字,value 是这个数字的 2 次方。

    dict1 = {i: i**2 for i in range(1, 5)}
    print(dict1)  # {1: 1, 2: 4, 3: 9, 4: 16}
    
  2. 将两个列表合并为一个字典

    list1 = ['name', 'age', 'gender']
    list2 = ['Tom', 20, 'man']
    
    dict1 = {list1[i]: list2[i] for i in range(min(len(list1), len(list2)))}
    print(dict1)  # {'name': 'Tom', 'age': 20, 'gender': 'man'}
    

    注意:

    1. 如果两个列表数据个数相同时,len 统计任何一个列表的长度都可以。
    2. 如果两个列表数据个数不同时,len 统计数据多的列表数据个数会报错;len统计数据少的列表数据的个数不会报错。
  3. 提取字典中目标数据

    # 提取上述电脑数量大于等于 200 的字典数据
    counts = {'MBP': 268, 'HP': 125, 'DELL': 201, 'Lenovo': 199, 'acer': 99}
    dict1 = {key: value for key, value in counts.items() if value >= 200}
    print(dict1)  # {'MBP': 268, 'DELL': 201}
    

2.3 集合推导式

# 需求:创建一个集合,数据为下方列表的2次方。
list1 = [1, 1, 2]

set1 = {i ** 2 for i in list1}
print(set1)  # {1, 4}  -- 去重

三、函数

3.1 函数的定义

  • 不带参数:

    def 函数名():
       	代码...
    
  • 带参数:

    def 函数名(参数):
       	代码...
    
  • 有返回值:

    def 函数名(参数):
       	代码...
    	return 返回值
    

    其中,参数可有可无。

  • 调用函数:
    函数名()

  • 示例:

    # 不带参数
    def fun():
        print('hello python')
    
    fun()  # hello python
    
    # 带参数
    def add_num(a, b):
        result = a + b
        print(result)
    
    add_num(2, 4)  # 6 
    
    # 有返回值
    def sum_num(a, b):
        return a + b
    
    print(sum_num(30, 40))  # 70
    

    注意:Python中,函数必须 先定义后使用


3.2 函数的说明文档

语法:

# 定义函数的说明文档
def 函数名(参数):
	""" 说明⽂文档的位置 """
	代码
	......

# 查看函数的说明文档
help(函数名) 

注意: 函数说明文档只能在第一行进行说明

def sum_num(a, b):
    '''求和函数'''
    return a + b

help(sum_num)

Python 基础入门笔记(三)———— 公共操作、推导式、函数、lambda表达式、高阶函数_第1张图片

函数说明文档的高级使用:回车可见参数信息

def sum_num1(a, b):
    """
    参数信息
    :param a:
    :param b:
    :return:
    """
    return a + b

help(sum_num1)

Python 基础入门笔记(三)———— 公共操作、推导式、函数、lambda表达式、高阶函数_第2张图片


3.3 变量的作用域

  • 局部变量
    局部变量是定义在函数体内部的变量量,即只在函数体内部生效。当函数调用完成后,则销毁局部变量。

    def testA():
        a = 100
        print(a)
    
    testA()
    
    print(a) # 报错,编译通不过
    
  • 全局变量
    全局变量,指的是在函数体内、外都能生效的变量。

    a = 100
    def testA():
        # a = 200  # 访问局部变量 a,对全局变量没有影响
        
        global a  # global 关键字声明 a 是全局变量
        a = 200  # 修改全局变量 a
        print(a)
    
    testA()  # 200
    print(a)  # 200
    

    注意: 在函数里修改全局变量,必须用 global 声明,否则修改的是局部变量


3.4 函数的返回值

当函数有 多个返回值 时,有如下写法:

def return_num():
	# return 1, 2  # 默认返回元组 (1, 2)
	# return (1, 2)  # 返回元组 (1, 2)
    # return [1, 2]  # 返回列表 [1, 2] 
    return {"name":"Kevin", "age":20}  # 返回字典 {"name":"Kevin", "age":20}

result = return_num()
print(result) 

注意:

  1. 只执行第一个 return
  2. return a,b 写法,返回多个数据的时候,默认是元组类型。
  3. return 后面可以连接列表、元组或字典,以返回多个值。

3.5 函数的参数

3.5.1 位置参数

位置参数: 调用函数时 根据函数定义的参数位置 来传递参数。

def user_info(name, age, gender):
    print(f'名字是{name}, 年龄是{age}, 性别是{gender}')

user_info('Kevin', 23, '男')  # 名字是Kevin, 年龄是23, 性别是男
# user_info('Kevin', 23)  # 报错
user_info(23, 'Kevin', '男')  # 名字是23, 年龄是Kevin, 性别是男

注意: 传递和定义参数的顺序及个数必须一致


3.5.2 关键字参数

函数调用,通过 键=值 形式加以指定。

def user_info(name, age, gender):
    print(f'名字是{name}, 年龄是{age}, 性别是{gender}')
    
# 实参不加引号
user_info('Kevin', age = 23, gender = '男')  # 名字是Kevin, 年龄是23, 性别是男
user_info(gender = '男', name = 'Kevin', age = 23)  # 名字是Kevin, 年龄是23, 性别是男
# 位置参数必须在关键字参数前面
# user_info(gender = '男', name = 'Kevin', 23)  # 报错,因为 23 是位置参数,其在关键字参数后面

注意: 函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面但关键字参数之间不存在先后顺序


3.5.3 缺省参数(默认参数)

缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值。

def user_info(name, age, gender='男'):
    print(f'名字是{name}, 年龄是{age}, 性别是{gender}')

user_info('Kevin', 23)  # 名字是Kevin, 年龄是23, 性别是男
user_info('Kevin', 23, '女')  # 名字是Kevin, 年龄是23, 性别是女

# 注意:所有位置参数必须出现在默认参数前,包括函数定义和调⽤
# def user_info1(name, age=23, gender): # 报错
#     print(f'名字是{name}, 年龄是{age}, 性别是{gender}')

注意: 所有位置参数必须出现在默认参数前,包括函数定义和调用


3.5.4 不定长参数(可变参数)

不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。

  • 包裹位置传递:返回值是 元组类型

    def user_info(*args):  # 一般用 args
        print(args)
    
    # 传进的所有参数都会被 args 变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递
    user_info()  # ()
    user_info('Kevin')  # ('Kevin',)
    user_info('Kevin', 20)  # ('Kevin', 20)
    user_info('Kevin', 20, '男')  # ('Kevin', 20, '男')
    
  • 包裹位置传递:返回值是 字典类型

    def user_info(**kwargs):  # 一般用 kwargs
        print(kwargs)
    
    user_info()  # {}
    user_info(name = 'Kevin', age = 20)  # {'name': 'Kevin', 'age': 20}
    

综上: 无论是包裹位置传递还是包裹关键字传递,都是一个 组包 的过程。


3.6 拆包和交换变量值

3.6.1 拆包

  • 拆包:元组

    def return_num():
        return 1, 2  # 返回值默认元组类型 
    
    num1, num2 = return_num()
    print(num1)  # 1
    print(num2)  # 2
    
  • 拆包:字典

    dict1 = {'name': 'Kevin', 'age': '20'}
    a, b = dict1
    
    #  对字典进行拆包,取出来的是字典的 key
    print(a)  # name
    print(b)  # age
    
    print(dict1[a])  # Kevin
    print(dict1[b])  # 20
    

3.6.2 交换变量值

a = 1
b = 2

# 法一:
'''
c = a
a = b
b = c
print(a, b)  # 2 1
'''

# 法二:
a, b = b, a
print(a, b)  # 2 1

3.7 引用

在 python 中,值是靠引用来相互传递。课用 id() 来判断两个变量是否为一个值的引用。(id 可以理解为变量开辟的内存地址)

3.7.1 了解引用

# 1. int 类型 --- 不可变类型

a = 1
b = a
# a 与 b 的 id 值相同
print(id(a) == id(b))  # True

a = 2
print(b)  # 1
# a 与 b 的 id 值不同
print(id(a) == id(b))  # False


# 2. 列表 -- 可变数据类型

aa = [10, 20]
bb = aa
# aa 与 bb 的 id 值相同
print(id(aa) == id(bb))  # True

aa.append(30)
print(bb)  # [10, 20, 30]
# id 值相同
print(id(aa) == id(bb))  # True

总结:

  • 不可变数据类型对数据进行修改时,相当于在内存中重新开辟了一块内存空间来存储变量值或者说重新创建了一个对象
  • 可变数据类型对数据进行修改时,没有开辟新的内存空间即没有创建新的对象

3.7.2 引用当实参

# 不可变数据类型
def testA(a):
    a = 6
    print(f"函数内:{a}, 内存地址:{id(a)}")

a = 0
testA(a)
print(f"函数外:{a}, 内存地址:{id(a)}")

Python 基础入门笔记(三)———— 公共操作、推导式、函数、lambda表达式、高阶函数_第3张图片

# 可变数据类型
def testB(a):
    a.append(30)
    print(f"函数内:{a}, 内存地址:{id(a)}")

a = [11, 22]
testB(a)
print(f"函数外:{a}, 内存地址:{id(a)}")  # id 值相同
print(a)

Python 基础入门笔记(三)———— 公共操作、推导式、函数、lambda表达式、高阶函数_第4张图片
总结:

  • 不可变数据类型作为参数时,在函数内对变量进行赋值,相当于重新开辟了一个内存空间来存储临时变量值,或者说重新创建一个对象去指向所赋的值
  • 可变数据类型作为参数, 在函数内外修改的都是同一个对象
  • 注意结合变量作用域进行区分理解,如果是刻板数据类型在函数体内进行修改,相当于修改全局变量。

3.8 递归

递归特点: 函数内部自己调用自己,且必须有出口

# 数字以内累加和,如:3 + 2 + 1
def sum_numbers(num):
    if num == 1:
        return 1
    return num + sum_numbers(num-1)

result = sum_numbers(3)
print(result)  # 6

四、lambda表达式

如果一个函数有一个返回值,并且只有一句代码,可以使用 lambda 简化。

4.1 lambda表达式语法

语法: lambda 参数列表︰表达式

注意:

  1. lambda 表达式的参数可有可无,函数的参数在 lambda 表达式中完全适用。
  2. lambda 函数能接收任何数量的参数 但只能返回一个表达式的值
# 测试函数
def fun1():
    return 100

print(fun1())  # 100


# lamdba 表达式化简上式
fun2 = lambda : 100
print(fun2)  #  at 0x0000023F6F523E20>
print(fun2())  # 100

需求:实现两数相加

# 测试函数
def add(a, b):
    return a + b

# lamdba 表达式化简上式
fun1 = lambda a, b: a + b
print(fun1)  #  at 0x000001D0BCECA560>
print(fun1(1, 2))  # 3

4.2 lambda表达式的参数

4.2.1 无参数

fn1 = lambda : 100
print(fn1())  # 100

4.2.2 有参数

fn2 = lambda a: a
print(fn2('hello'))  # hello

4.2.3 默认参数

fn3 = lambda a, b, c = 100: a + b + c
print(fn3(1,2))  # 103

4.2.4 可变参数

# 可变参数:*args
fn4 = lambda *args: args
print(fn4(1))  # (1,)
print(fn4(1, 2, 3))  # (1, 2, 3)

# 可变参数 **kwargs
fn5 = lambda **kwargs: kwargs
print(fn5(name = 'python'))  # {'name': 'python'}
print(fn5(name = 'python', age = 20))  # {'name': 'python', 'age': 20}

4.3 lambda表达式的应用

4.3.1 带判断的lambda

fn1 = lambda a, b: a if a > b else b  # 三目运算符
print(fn1(100, 200))  # 200

4.3.2 列表数据按字典key的值排序

students = [
{'name': 'TOM', 'age': 20},
{'name': 'ROSE', 'age': 19},
{'name': 'Jack', 'age': 22}]

# 按 name 值升序排列
students.sort(key = lambda x: x['name'])  # x 指代待排序的元素或数据
print(students)  # [{'name': 'Jack', 'age': 22}, {'name': 'ROSE', 'age': 19}, {'name': 'TOM', 'age': 20}]

# 按 name 值降序排列
students.sort(key = lambda x: x['name'], reverse=True)
print(students)  # [{'name': 'TOM', 'age': 20}, {'name': 'ROSE', 'age': 19}, {'name': 'Jack', 'age': 22}]

# 按 age 值升序排列
students.sort(key = lambda x: x['age'])
print(students)  # [{'name': 'ROSE', 'age': 19}, {'name': 'TOM', 'age': 20}, {'name': 'Jack', 'age': 22}]

注意:key = lambda x: x['name'] 中 x 指代待排序的元素或数据。


五、高阶函数

把函数作为参数传入,这样的函数称为高阶函数,高阶函数是函数式编程的体现。函数式编程就是指这种高度抽象的编程范式。

高阶函数示例:

5.1 高阶函数示例

# 需求:任意两个数字,先进行数字处理(绝对值或四舍五入)在求和计算
# abs 取绝对值,round 四舍五入

# 1. 法一:
def add_num(a, b): # 只能进行绝对值处理,如果四舍五入还需要再写另一个函数
    return abs(a) + abs(b)

result1 = add_num(-1.1, 1.9)
print(result1)

# 2. 法二:
def add_num2(a, b, f):  # f 是函数参数
    return f(a) + f(b)

print(add_num2(-1.1, 1.9, abs))  # 3.0
print(add_num2(-1.1, 1.9, round))  # 1

5.2 内置高阶函数

5.2.1 map()

map(func, Ist),将传入的函数变量 func 作用到 lst 变量的每个元素中,并将结果组成新的迭代器(Python3)返回。注:Python2 中是作为列表返回。

示例:

# 计算 list1 序列中各个数字的2次方。
list1 = [1, 2, 3, 4]

def func(x):
    return x ** 2

result = map(func, list1)
print(result)  # 迭代器 
print(list(result))  # 转换数据类型 [1, 4, 9, 16]

5.2.2 reduce()

reduce(func(x,y), lst)其中 func 必须有两个参数。每次func计算的结果继续和序列的下一个元素做累积计算。

示例:

# 计算 list1 序列中各个数字的累加和。
import functools
list1 = [1, 2, 3, 4]

def func(a, b):
    return a + b

result = functools.reduce(func, list1)
print(result)  # 10

5.2.3 filter()

filter(func, lst) 用于过滤序列,返回一个 filter 对象,如果要转换为列表,可以使用 list() 来转换。

示例:

# 在 list1 中提取偶数序列
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def func(x):
    return x % 2 == 0

result = filter(func, list1)
print(result)  # 
print(list(result))  # [2, 4, 6, 8, 10]

你可能感兴趣的:(Python,python,开发语言,函数式编程,lambda)