Python学习笔记2

Python基础

1 运算符

运算符用于执行某种操作并返回一个结果,Python中的运算符可以分为:

1.1 算术运算符

用于执行基本的数学运算

1.1.1 常见运算符
  • +:加法

  • -:减法

  • *:乘法

  • /:除法

  • %:取模(取余数)

  • **:幂运算

  • //:整除(取整数部分)

1.2 比较运算符

用于比较两个值并返回布尔值 True 或 False

  • ==:等于

  • !=:不等于

  • <:小于

  • >:大于

  • <=:小于等于

  • >=:大于等于

1.3 逻辑运算符

用于连接布尔值并返回结果

1.3.1 运算符
  • and:与(逻辑与)

  • or:或(逻辑或)

  • not:非(逻辑非)

1.3.2 运算规则
  • and 与运算:两者同时为真,结果才为真

    • 语法

      x and y   # x, y代表表达式

    • 示例

      3 + 4 > 5 and 6 + 7 > 100
      False

    • 真值表

      x的值 y的值 x and y的值
      True True True
      True False False
      False True False
      False False False

      优先返回假值对象, 如果x 为假值,返回x, 否则返回y

  • or 或运算:只要有一个为真,结果就为真

    • 语法

      x or y   # x, y代表表达式

    • 真值表

      x的值 y的值 x or y的值
      True True True
      True False True
      False True True
      False False False

      优先返回真值对象, 如果x 为真值,返回x, 否则返回y

  • not 非运算:将表达式的结果取 操作

    not 运算符是一元运算符

    • 语法

      not 表达式

    • 示例

      not True    # False
      not False   # True
      not 3.14    # False
      not ''      # True
      not 1 + 2   # False

1.4 赋值运算符

用于给变量赋值

  • =:赋值

  • +=:加法赋值

  • -=:减法赋值

  • *=:乘法赋值

  • /=:除法赋值

  • %=:取模赋值

  • **=:幂运算赋值

  • //=:整除赋值

    注意:

    没有 a++、 a-- 这种自增自减运算符;(学过c的都犯过)

1.5 位运算符

用于对整数按位进行操作

2.5.1 常见运算符
  • &:按位与

  • |:按位或

  • ^:按位异或

  • ~:按位取反

  • <<:左移位

  • >>:右移位

1.5.2 运算规则
  1. 按位与(&)

    • 表达式:a & b

    • 功能:对于每一位,如果a和b的相应位都是1,则结果位为1,否则为0。

      # 示例:计算两个二进制数的按位与
      a = 0b1011  # 二进制表示的11
      b = 0b1101  # 二进制表示的13
      result_and = a & b  # 计算两者之间的按位与
      print(bin(result_and))  # 输出:0b1001 (十进制为9)
  2. 按位或(|)

    • 表达式:a | b

    • 功能:对于每一位,只要a和b中至少有一位是1,则结果位为1,否则为0。

      # 示例:计算两个二进制数的按位或
      a = 0b1011
      b = 0b1101
      result_or = a | b  # 计算两者之间的按位或
      print(bin(result_or))  # 输出:0b1111 (十进制为15)

  3. 按位异或(^)

    • 表达式:a ^ b

    • 功能:对于每一位,如果a和b的相应位不同(一个为1,另一个为0),则结果位为1,否则为0。

      # 示例:计算两个二进制数的按位异或
      a = 0b1011
      b = 0b1101
      result_xor = a ^ b  # 计算两者之间的按位异或
      print(bin(result_xor))  # 输出:0b110 (十进制为6)

  4. 按位取反(~)

    • 表达式:~a

    • 功能:对操作数a的每一个二进制位进行取反,即将1变为0,0变为1。

      # 示例:计算一个二进制数的按位取反
      a = 0b1011
      result_not = ~a  # 计算a的按位取反
      print(bin(result_not))  # 输出:-0b1100

  5. 左移运算符(<<)

    • 表达式:a << b

    • 功能:将a的二进制表示向左移动b位,左边移出的部分会被丢弃,右边空出的位置补零。相当于乘以$2^n$次方

    # 示例:将一个二进制数向左移动两位
    a = 0b1011
    result_left_shift = a << 2  # 将a向左移动两位
    print(bin(result_left_shift))  # 输出:0b101100 (十进制为44)

  6. 右移运算符(>>)

    • 表达式:a >> b

    • 功能:

      • 将a的二进制表示向右移动b位

      • 对于无符号整数,右边移出的部分会被丢弃,左边空出的位置补零(通常补0);

      • 对于有符号整数,右移时取决于具体实现,可能是算术右移(符号位扩展)或者逻辑右移(补0)。

      • 同理,相当于除以2^n

      # 示例:将一个有符号二进制数向右移动一位
      a = -0b1000  # 十进制为-8
      result_right_shift = a >> 1  # 将a向右移动一位
      print(bin(result_right_shift))  # 输出:-0b100 (十进制为-4)
      ​
      # 对于无符号数的例子
      unsigned_a = 0b1000
      unsigned_result_right_shift = unsigned_a >> 1
      print(bin(unsigned_result_right_shift))  # 输出:0b100 (十进制为4)

1.6 身份运算符

用于比较对象的内存地址(即身份)

  • is:判断对象是否相同

  • is not:判断对象是否不同

基础类型:值和类型都相同时,存在一个内存空间里面

a = 1
b = 1
print(a == b)  #True, 比较的是值
print(a is b)  #True, 比较的是内存地址,同一个值放在一个内存里面

基础类型:类型不同时就需要存放在两个内存空间里

a=1
b=1.0
a == b #True,值是相等的
a is b #False,需要放在两个内存空间里面,分别表示int和float

引用类型:有序列表

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) #True, 比较的是值
print(a is b) #False,比较的是内存地址

更多1:有序的列表list

a = [1, 2, 3]
b = [1, 3, 2]
print(a == b) #False,比较的是值,列表是有序的,值不同
print(a is b) #False,比较的是地址

更多2:无序的集合Set

a = {1, 2, 3}
b = {1, 3, 2}
print(a == b) #True,比较的是值,Set是无序的,所以值相同
print(a is b) #False,比较的是地址

更多3:无序的字典Dict

a = {'name': '张三', 'age': 10}
b = {'age': 10, 'name': '张三'}
print(a == b) #True,比较的是值,字典是无序的,所以值相同
print(a is b) #False,比较的是地址

1.7 成员运算符

用于检查一个值是否是某个集合的成员

  • in:判断值是否存在于序列中

  • not in:判断值是否不存在于序列中

1.8 三目运算符

条件运算符、三元运算符

max = a if a>b else b
#如果 a>b 成立,就把 a 作为整个表达式的值,并赋给变量 max;
#如果 a> b 不成立,就把 b 作为整个表达式的值,并赋给变量 max。

1.9 优先级

运算符 描述
**
~ 按位“取反”
*、/、%、// 乘、除、取模、取整除
+、- 加、减
>>、<< 右移、左移
& 按位“与”
^、 按位“异或”、按位“或”
<=、<、>、>= 比较运算符
==、!= 等于、不等于
=、%=、/=、//=、-=、+=、*=、**= 赋值运算符
is、is not 身份运算符
in、not in 成员运算符
and or not 逻辑运算符

PS:更多的时候,我们借助()来明确优先级问题。

2. 表达式

表达式(expression)是由一个或多个操作数和运算符组成的。简单来说,表达式可以是任何会产生一个值的代码片段。

2.1 算术表达式

涉及数学运算的表达式。例如:

a = 5
b = 3
result = a + b  # 加法
result = a / b  # 除法
result = a // b  # 地板除
result = a % b  # 取余
result = a ** b  # 幂运算

2.2 比较表达式

用于比较两个值,通常返回布尔值 TrueFalse

a = 5
b = 3
result = a > b  # 大于
result = a <= b  # 小于等于

2.3 逻辑表达式

用于连接布尔值,返回布尔值 TrueFalse

a = True
b = False
result = a and b  # 逻辑与
result = a or b  # 逻辑或
result = not a  # 逻辑非

2.4 赋值表达式

将一个值赋给一个变量,通常用 = 运算符。

a = 5  # 赋值表达式
b = a + 3  # 计算并赋值

Python 3.8+ 引入了 海象运算符:=),这是一种新的赋值表达式,允许在表达式中直接给变量赋值:

if (n := len(data)) > 10:  # 给n赋值并使用
    print(f"列表长度大于10,长度为{n}")

2.5 成员表达式

用于检查一个值是否在序列、集合或字典中。

a = [1, 2, 3]
result = 2 in a  # 检查2是否在列表a中
result = 4 not in a  # 检查4是否不在列表a中

2.6 身份表达式

用于比较两个对象的身份(即是否是同一个对象),返回布尔值。

a = [1, 2]
b = a
result = a is b  # 判断a和b是否是同一个对象
result = a is not b  # 判断a和b是否不是同一个对象

2.7 三元表达式

简化的 if-else 表达式,根据条件选择两个值之一。

a = 5
b = 3
result = a if a > b else b  # 如果a > b,result为a,否则为b

2.8 函数调用表达式

调用函数并返回结果。

def add(x, y):
    return x + y
​
result = add(5, 3)  # 函数调用表达式

2.9 推导式

用更简洁的方式创建列表、字典和集合。是 Python 特有的一种表达式形式。

2.9.1 列表推导式
a = [1, 2, 3, 4]
result = [x * 2 for x in a]  # 创建一个新列表,元素是原列表每个元素的两倍
2.9.2 字典推导式
a = ['a', 'b', 'c']
result = {x: ord(x) for x in a}  # 创建一个字典,将字母映射到对应的ASCII值
2.9.3 集合推导式
a = [1, 2, 3, 4]
result = {x * 2 for x in a}  # 创建一个集合,元素是原列表每个元素的两倍

2.10 Lambda表达式

匿名函数的简化表达式,用于创建小型、一次性的函数。

f = lambda x, y: x + y  # 创建一个匿名函数
result = f(2, 3)  # 调用匿名函数

2.11 生成器表达式

类似于列表推导式,但是返回的是一个生成器对象,而不是一个完整的列表。

a = [1, 2, 3, 4]
result = (x * 2 for x in a)  # 创建一个生成器,元素是原列表每个元素的两倍

2.12 调用运算符()

在 Python 中,圆括号也可以用来创建表达式,通常用于控制运算顺序或者在函数调用时传递参数。

result = (5 + 3) * 2  # 使用括号改变运算顺序

2.13 表达式的求值顺序

Python 中的表达式按照运算符优先级规则求值。运算符优先级的规则决定了不同类型的运算在计算时的顺序。

3. 语句

语句是计算机执行程序的最小单位。

3.1 赋值语句

赋值语句将一个值赋给变量:

a = 5  # 将值 5 赋给变量 a
b = a + 2  # 计算 a + 2 并将结果赋给 b

3.2 条件语句

条件语句用于根据不同的条件来执行不同的代码块。常见的条件语句有 ifelifelse

语法

if 条件表达式1:
   语句块1
elif 条件表达式2:
   语句块2
...
elif 条件表达式n:
   语句块n
else:
   语句块(其他)

x = 10
if x > 0:
    print("x 是正数")
elif x == 0:
    print("x 是零")
else:
    print("x 是负数")

3.3 循环语句

循环语句用于重复执行一段代码,直到满足某个条件。常见的循环语句有 for 循环和 while 循环。

3.3.1 for循环

遍历可迭代对象(如列表、元组、字典等)

遍历是指经历且只经历一遍

可迭代对象是指能够依次获取数据元素的对象

for i in range(5):
    print(i)  # 输出 0, 1, 2, 3, 4
3.3.2 while循环

当条件为 $True$ 时重复执行

  • 语法

    while 真值表达式:
       语句块1  (*此部分可能会重复执行)
    else:
       语句块2

  • count = 0
    while count < 5:
        print(count)
        count += 1  # 输出 0, 1, 2, 3, 4
     
  • PS:while循环是可以嵌套的

3.3.3 range
  • 作用

    用来生成一个能够得到一系列整数的可迭代对象(也叫整数序列生成器)

  • 调用格式

    range(stop)                 # stop 停止整数
    range(start, stop)          # start 开始整数
    range(start, stop, step)    # step 步长

    range 函数调用会生成从 start 开始,到 stop 结束(不包含stop) 的一系列整数,整数的间隔 step

    start 默认值为0, step 默认值为1

  • 示意

    range(4)          # 生成 0 1 2 3
    range(3, 6)       # 生成 3 4 5
    range(1, 10, 2)   # 生成 1 3 5 7 9
    range(5, 0, -2)   # 生成 5 3 1

3.4 死循环

  • 死循环是指循环条件一直成立的循环

  • 死循环通常使用 break 语句来终止循环

3.5 循环控制语句

跳转语句用于控制程序的执行流程。

3.5.1 break

跳出当前循环。

for i in range(5):
    if i == 3:
        break  # 退出循环
    print(i)
# 输出:0, 1, 2
3.5.2 continue

跳过当前循环,继续下一次循环。

for i in range(5):
    if i == 3:
        continue  # 跳过打印 3
    print(i)
# 输出:0, 1, 2, 4
3.5.3 pass

占位符,什么也不做,通常用于占据语法上必须有代码的地方。

3.7 函数定义语句

用于定义一个函数,包含 def 关键字:

def greet(name):
    print(f"Hello, {name}!")
​
greet("Alice")  # 调用函数

3.8 异常处理语句

用于捕获和处理可能出现的错误。通过 tryexceptelsefinally 来定义异常处理流程:

try:
    result = 10 / 0  # 触发异常
except ZeroDivisionError:
    print("除数不能为零")
else:
    print("没有错误")
finally:
    print("无论如何都会执行")

3.9 导入语句

导入语句用于导入模块或包,使得程序可以使用外部代码和库:

import math  # 导入math模块
print(math.sqrt(16))  # 使用math模块中的sqrt函数

3.10 注释语句

注释语句用于解释代码,Python 解释器会忽略这些注释。单行注释使用 #,多行注释可以用三个引号:

# 这是一个单行注释
x = 5  # 这是一个行尾注释
​
"""
这是一个多行注释
可以用于更长的解释
"""

3.11 类定义语句

用于定义一个类,类中包含属性和方法:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def greet(self):
        print(f"Hello, my name is {self.name} and I am {self.age} years old.")
​
p = Person("Alice", 30)
p.greet()  # 调用类的方法

3.12 with语句

with 语句用于处理资源管理(如文件操作),确保资源在使用后被正确关闭或释放:

with open("file.txt", "r") as file:
    content = file.read()
    print(content)

Python函数

1. 基础认知

编程中的函数大抵如此,描述了一种“输入-输出”的关系。

1.1 函数的概念

  • 概念

    函数是可以重复执行的语句块,可以重复调用

  • 作用

    用于封装语句块,提高代码的重用性。

  • 定位

    函数是面向过程编程的最小单位

1.2 函数的定义

使用def 语句定义一个函数a

  • 语法

    def function_name(parameters):
        # 函数体
        # 进行一些操作
        return result  # 可选的返回值
  • 说明

    1. def:用于声明一个函数,告诉 Python 这是一个函数的定义。

    2. function_name:函数名,一个有效的标识符,规则和变量名一致。

    3. parameters:形参,可以是0 ~ n 个,参数之间用逗号分隔。

    4. 函数体:定义函数执行的具体操作。

    5. return:指定函数的返回值,没有则返回None。

    6. return之后的代码不会执行。

2. 内置函数

Python提供了大量的可直接使用的内置函数,主要执行一些常见的操作:数据处理、类型转换、数学计算、输入输出等。

官方地址:https://docs.python.org/zh-cn/3.13/library/functions.html

2.1 all()

如果可迭代对象中的所有元素都为 True,返回 True,否则返回 False

print(all([True, True, False]))  # 输出: False
print(all([1, 2, 3]))           # 输出: True

2.2 sum()

返回可迭代对象中所有元素的总和。

print(sum([1, 2, 3]))  # 输出: 6

2.3 sorted()

返回一个新列表,其中包含可迭代对象中的元素,按照升序排序。

print(sorted([3, 1, 2]))  # 输出: [1, 2, 3]
x=[-10,20,19,21,-30,0]
def fn(x):
    return (x-20)**2
re=sorted(x,key=fn)#参数 key=fn 表示在排序时,不是直接比较列表中的元素,而是比较每个元素通过函数 fn 处理后的结果。
print(re)

2.4 reversed()

返回一个反向迭代器。

print(list(reversed([1, 2, 3])))  # 输出: [3, 2, 1]

2.5 callable()

检查对象是否可以被调用(即是否是函数或方法)。

print(callable(print))  # 输出: True
print(callable(123))    # 输出: False

2.6 zip()

将多个可迭代对象打包成一个元组,常用于并行遍历多个序列。

names = ["Alice", "Bob"]
ages = [25, 30]
zipped = zip(names, ages)
print(list(zipped))  # 输出: [('Alice', 25), ('Bob', 30)]

2.7 eval()

将字符串作为有效的 Python 表达式来执行,并返回结果。

x = 10
result = eval("x + 5")
print(result)  # 输出: 15

2.8 exec()

执行存储在字符串中的 Python 代码。

code = 'for i in range(3): print(i)'
exec(code)
# 输出:
# 0
# 1
# 2

2.9 globals()locals()

globals() 返回当前全局符号表(一个字典);locals() 返回当前局部符号表(也是字典)。

x = 10
print(globals())  # 输出: 包含全局变量的信息
print(locals())   # 输出: 包含局部变量的信息

2.10 filter()

从可迭代对象中过滤出符合条件的元素。

numbers = [1, 2, 3, 4, 5]
filtered = filter(lambda x: x % 2 == 0, numbers)
print(list(filtered))  # 输出: [2, 4]

3. 函数的调用

函数名后面跟上 小括号() 表示函数的执行。

3.1 基本用法

  • 语法

    函数名(实际调用传递参数)
  • 说明

    函数调用是一个表达式,我的意思是他可以参与运算

  • 示例

    add(3, 5)       # 直接调用
    add(3, 5) + 6   #直接参与运算

3.2 调用传参

函数调用时传递参数的方式有多种,包括位置传参、关键词传参、多个参数解包、参数默认值等。

3.2.1 位置传参

最常见的传参方式,参数按定义的顺序依次传入函数。

示例:

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")
​
greet("Alice", 30)  # 输出: Hello, Alice. You are 30 years old.

3.2.2 关键词传参

通过指定参数的名称来传值,无顺序限制,代码可读性较高。

示例:

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")
​
greet(age=30, name="Alice")  # 输出: Hello, Alice. You are 30 years ol
d.

3.2.3 参数默认值

定义函数时可为某些参数指定默认值,如果不传参则使用默认值。默认值参数必须位于无默认值参数的后面。

示例:

def greet(name, age=25):
    print(f"Hello, {name}. You are {age} years old.")
​
greet("Alice")       # 输出: Hello, Alice. You are 25 years old.
greet("Bob", 30)     # 输出: Hello, Bob. You are 30 years old.

3.2.4 可变位置参数

使用 $args$ 可让函数接受任意数量的位置参数。$args$ 会将多余的位置参数收集成一个元组。

示例:

def sum_numbers(*args):
    return sum(args)
​
print(sum_numbers(1, 2, 3))     # 输出: 6
print(sum_numbers(1, 2, 3, 4))  # 输出: 10

3.2.5 可变关键词参数

使用 $kwargs$ 可以让函数接受任意数量的关键词参数。$kwargs$ 会将多余的关键词参数收集成一个字典。

示例:

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")
​
print_info(name="Alice", age=30)
# 输出:
# name: Alice
# age: 30

3.2.6 多参数解包

Python 允许在调用函数时解包序列或字典,使其作为位置参数或关键词参数传递给函数。

3.2.6.1 解包位置参数

使用 $*$ 解包

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")
​
args = ["Alice", 30]
greet(*args)  # 输出: Hello, Alice. You are 30 years old.

3.2.6.2 解包关键词参数

使用 ** 解包

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")
​
kwargs = {"name": "Alice", "age": 30}
greet(**kwargs)  # 输出: Hello, Alice. You are 30 years old.

3.2.7 参数混合使用

在函数调用时,可以混合使用位置参数和关键词参数,但位置参数必须放在关键词参数前面。

示例:

def greet(name, age, city="Unknown"):
    print(f"Hello, {name}. You are {age} years old and live in {city}.")
​
greet("Alice", 30)              # 输出: Hello, Alice. You are 30 years old and live in Unknown.
greet("Bob", 25, city="New York")  # 输出: Hello, Bob. You are 25 years old and live in New York.

4. 可变和不可变参数

在 Python 中,实参可以是可变类型或不可变类型。它们的区别主要体现在值传递引用传递的行为上。

4.1 不可变类型

不可变类型包括:$int、float、str、tuple、frozenset$ 等。

传递方式是值传递: 传递给函数的是该对象的值,函数内部修改该值不会影响外部变量的值。

示例:

def modify(x):
    print('修改之前:', x, id(x))
    x = 10          # 修改了 x 的值,但不会影响外部变量
    print('修改之后:',x, id(x))
​
a = 5
modify(a)
print('原始数据:',a, id(a))
#打印结果:

#修改之前: 5 140722275297848
#修改之后: 10 140722275298008
#原始数据: 5 140722275297848

4.2 可变类型

可变类型包括:$list、dict、set$ 等。这些类型的对象可以在原地修改。

传递方式是引用传递 :传递给函数的是对象的引用(即内存地址),在函数内部修改该参数的内容会直接影响外部变量。

示例:

def modify(lst):
    print('修改之前:', lst, id(lst))
    lst.append(4)  # 修改了 lst 对象的内容
    print('修改之后:',lst, id(lst))
​
a = [1, 2, 3]
modify(a)
print('外部原始数据:',a, id(a)) 
#打印结果:

#修改之前: [1, 2, 3] 2123053058816
#修改之后: [1, 2, 3, 4] 2123053058816
#外部原始数据: [1, 2, 3, 4] 2123053058816

3.3 避免副作用

通过复制对象来避免可变类型副作用:

  • 列表:使用 lst.copy() 或切片 lst[:] 来创建一个副本。

  • 字典:使用 dict.copy()copy.deepcopy() 来进行深拷贝。

  • 元组:推荐用tuple 创建新的元组,虽然本身就是不可变。

示例:

def modify(lst):
    lst_copy = lst.copy()  # 创建副本
    lst_copy.append(4)      # 修改副本
​
a = [1, 2, 3]
modify(a)
print(a)  # 输出: [1, 2, 3] (外部列表不受影响

5. 匿名函数

匿名函数是没有名字的函数,通常用于需要一个简短的、临时的函数场景,它可以有任意数量的参数,但只能包含一个表达式,并返回该表达式的结果。

5.1 基本语法

lambda arguments: expression

  • arguments:一个或多个输入参数,可以是位置参数或关键词参数。

  • expression:一个单一的表达式,它的值将作为返回值返回。

5.2 匿名函数定义

# 定义一个 lambda 函数,接收两个参数 a 和 b,返回它们的和
add = lambda a, b: a + b
​
print(add(3, 5))  # 输出: 8

5.3 使用场景

lambda 函数常常与高阶函数如 map()filter()sorted() 等一起使用。

  • 处理列表

numbers = [1, 2, 3, 4, 5]
# 使用 map() 将每个数字平方
squared_numbers = list(map(lambda x: x ** 2, numbers))
​
print(squared_numbers)  # 输出: [1, 4, 9, 16, 25]
  • 筛选列表

numbers = [1, 2, 3, 4, 5, 6]
# 使用 filter() 筛选出偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
​
print(even_numbers)  # 输出: [2, 4, 6]
  • 实现排序

# 按照字典的值排序
dict_list = [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}, {"name": "Charlie", "age": 35}]
# 按照 age 排序
sorted_dict_list = sorted(dict_list, key=lambda x: x["age"])
​
print(sorted_dict_list)
# 输出: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]

5.4 条件表达式

你可以在 lambda 函数中使用条件表达式(if-else)来做一些简单的决策。

# 判断是否为偶数
is_even = lambda x: "Even" if x % 2 == 0 else "Odd"
​
print(is_even(4))  # 输出: Even
print(is_even(7))  # 输出: Odd

5.5 匿名函数优点

  1. 结构简单lambda 函数通常用在需要一个短小函数的地方,而普通函数则更适合复杂的逻辑。

  2. 匿名性lambda 函数是没有名字的,它们通常只在一个地方使用,并且不需要被重复调用。

  3. 功能限制lambda 函数只能包含一个表达式,不可以包含多行语句,而普通函数可以包含多行代码、条件判断、循环等复杂逻辑。

6. 高阶函数

高阶函数是指可以接受一个或多个函数作为参数,或者返回一个函数作为结果的函数。

6.1 常见高阶函数

比较常用,单独拎出来熟悉一下

6.1.1 map

map(function, iterable)

map函数:

  • 接受一个函数和一个可迭代对象

  • 将接受的函数应用到可迭代对象的每个元素上

  • 返回一个包含结果的迭代器

numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
# squared现在包含[1, 4, 9, 16, 25]
6.1.2 filter

filter(function, iterable)

filter函数:

  • 接受一个函数和一个可迭代对象

  • 用接受的函数来筛选出可迭代对象中满足条件的元素

  • 返回一个包含满足条件的元素的迭代器

numbers = [1, 2, 3, 4, 5]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
# even_numbers现在包含[2, 4]
6.1.3 reduce

reduce(function, iterable[, initializer])

reduce函数:

  • reduce函数接受一个函数和一个可迭代对象

  • 将接受的函数累积地应用到可迭代对象的元素上

  • 可选的 $initializer$ 参数可以作为累积的初始值

from functools import reduce
​
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
# product现在包含120 (1 * 2 * 3 * 4 * 5)

6.2 作为参数

高阶函数可以接受其他函数作为参数,用于自定义行为。

def sort_custom_key(item):
    return item[1]
​
data = [('apple', 3), ('banana', 1), ('cherry', 2)]
sorted_data = sorted(data, key=sort_custom_key)
# sorted_data现在包含[('banana', 1), ('cherry', 2), ('apple', 3)]

7. 变量作用域

变量的作用域(Scope)是指在程序中某个变量的有效范围,也就是在代码的哪个部分可以访问或修改该变量。作用域定义了变量的可见性和生命周期。

Python中的变量作用域遵循LEGB规则(Local, Enclosing, Global, Built-in),依次搜索变量的定义位置。

7.1 Local→局部作用域

  • 指函数或方法内部定义的变量。

  • 仅在函数内部有效,函数外部无法访问。

  • 在函数调用时被创建,在函数调用后自动销毁。

  • 示例:

    def func():
        x = 10  # 局部变量

7.2 Enclosing→嵌套作用域

  • 指外层函数中的变量,在内层函数中可访问,但不可修改。

  • 当一个函数嵌套在另一个函数内部时,外层函数的变量属于Enclosing作用域。

  • 示例:

    def outer():
        x = 20  # 外层函数变量
        def inner():
            print(x)  # 访问外层函数变量
        inner()

  • nonlocal:将局部作用域中变量声明为外部嵌套函数作用域中的变量

    #外部嵌套作用域
    def func01():
        a = 10
        
        def func02():
            # 内部函数,如果修改外部嵌套变量,需要使用nonlocal语句声明
            nonlocal a
            a += 20
        func02()
        print(a)
        
    func01()

7.3 Global→全局作用域

  • 指模块级别定义的变量,整个模块都可以访问。

  • 如果想在函数中修改全局变量,需要使用global关键字。

  • 示例:如何用一个变量来记录一个函数调用的次数

    count = 0
    ​
    def hello(name):
        global count  # 声明 count 是全局变量
        print('hello', name)
        count += 1
    ​
    hello('小张')
    hello('小李')
    hello('小魏')
    ​
    print('您共调用hello函数', count, '次')

7.4 Built-in→内建作用域

  • 包含Python内建的函数、异常和常量,如print(), len(), int, Exception等。

  • 这些变量可以在任何地方使用。

  • 示例:

    print(len([1, 2, 3]))  # 使用内建函数len

7.5 变量查找顺序

作用域遵循LEGB规则(Local, Enclosing, Global, Built-in)

示例:

x = "global"
​
def outer():
    x = "enclosing"
    def inner():
        x = "local"
        print(x)  # 输出局部变量 'local'
    inner()
​
outer()

如果不使用 $global$ 关键字,函数内修改的会是局部变量,而不是全局变量。

8. 函数内存分配

1、将函数的代码存储到代码区,函数体中的代码不执行。

2、调用函数时,在内存中开辟空间(栈帧),存储函数内部定义的变量。

3、函数调用后,栈帧立即被释放。

def func(a, b):
    a = 20
    b[0] = 20
​
a = 10
b = [100]
func(a, b)
print(a) # 10
print(b) # [20]

9. 递归函数

递归是指函数直接或间接调用自身的过程。递归通常用于解决分解成相似子问题的复杂问题。

9.1 函数结构

递归函数通常由两个部分组成:

  1. 终止条件:用于确保递归能够停止,避免无限递归。

  2. 递归调用:函数在其内部调用自身,传递简化或减少的参数,以解决更小的子问题。

9.2 基本步骤

  1. 定义递归函数:在函数体内调用函数自身。

  2. 设定终止条件:确保递归能终止。

  3. 逐步简化问题:通过传递较小的参数递归求解,直至终止条件满足。

你可能感兴趣的:(python,学习,笔记)