函数进阶语法与面向过程

Python进阶语法与面向对象基础完整笔记

一、基础语法:分支判断与三元表达式

1.1 普通分支函数判断

通过自定义函数结合if判断,实现两个数值大小比对,返回最大值,是最基础的条件判断写法。

# 定义函数实现两数取最大值
def func(x, y):
    if x > y:
        return x
    else:
        return y

# 调用函数
res = func(10, 20)
print(res)

1.2 三元表达式(简洁判断语法)

三元表达式是if...else分支的极简写法,适用于简单的二选一判断,语法结构:结果1 if 条件 else 结果2。条件成立返回结果1,不成立返回结果2。

二、推导式:高效序列生成语法

推导式是Python专属的极简语法,可快速生成列表、字典、集合等序列数据,替代传统for循环拼接代码,简洁高效、执行速度更快。包含列表、生成器、字典、集合四大推导式。

2.1 列表推导式

用于快速生成、过滤、改造列表数据,支持单层循环、多层循环、条件筛选。

完整语法:

# [expression for item1 in iterable1 if condition1
# for item2 in iterable2 if condition2
# ...
# for itemN in iterableN if conditionN
# ]

等价于普通循环逻辑:

# res=[]
# for item1 in iterable1:
#     if condition1:
#         for item2 in iterable2:
#             if condition2:
#                 ...
#                 for itemN in iterableN:
#                     if conditionN:
#                         res.append(expression)

执行逻辑:循环遍历可迭代对象,满足条件则执行表达式,将结果存入新列表。

# 原始列表数据
l = ['egon', "lili_dsb", "jack_dsb", "tom_sb", "xxx_dsb"]

# 需求1:所有元素转为大写
new_l1 = [name.upper() for name in l]
print(new_l1)

# 需求2:所有元素去掉末尾sb
new_l2 = [name.strip("sb") for name in l]
print(new_l2)

# 需求3:筛选出以sb结尾的元素
new_l3 = [name for name in l if name.endswith("sb")]
print(new_l3)

2.2 生成器表达式

语法与列表推导式几乎一致,将[]改为(),不直接生成完整列表,而是生成一个迭代器对象,惰性求值,节省内存,适合处理海量数据。

# 生成器创建
chicken = ("鸡蛋%s" % i for i in range(5))
print(chicken)  # 输出生成器对象,不占用大量内存

# 逐个取值
print(next(chicken))
print(next(chicken))
print(next(chicken))
print(next(chicken))
print(next(chicken))

# 强制转换为列表(取值完毕后生成器为空)
res1 = list(chicken)
print(res1)
res2 = list(chicken)
print(res2)  # 再次取值为空

文件读取场景优化:利用生成器惰性特性,避免一次性读取大文件占用内存

with open("a.txt",mode='rt',encoding='utf-8') as f:
    # 方式一:一次性读取全部内容
    res = f.read()
    print(len(res))

    # 方式二:循环逐行累加
    res = 0
    for line in f:
        res += len(line)
    print(res)

    # 方式三:列表推导式,一次性生成所有数据,占用内存高
    res = sum([len(line) for line in f])
    print(res)

    # 方式四:生成器表达式,惰性取值,内存占用极低(可省略小括号)
    res = sum(len(line) for line in f)
    print(res)

2.3 字典推导式

快速创建、改造字典,支持批量生成键值对、列表转字典等场景。

# 场景1:批量生成键值对
dic1 = {"k%s" %i:i for i in range(5)}
print(dic1)

# 场景2:批量初始化字典值为None
keys = ["name","age","gender"]
dic2 = {k:None for k in keys}
print(dic2)

# 场景3:二元元组列表转为字典
items = [('name',"egon"),("age",18),("gender",'male')]
dic3 = {k:v for k,v in items}
print(dic3)

2.4 集合推导式

快速生成集合,自动去重,语法结构与列表推导式一致,外层为{}。

res = {i for i in range(3)}
print(res,type(res))

三、函数递归调用

3.1 递归定义与特性

函数递归是函数嵌套调用的特殊形式:在函数调用过程中,直接或间接调用函数自身,本质是替代循环实现重复执行。

分类:

1、直接递归:函数内部直接调用自身;

2、间接递归:A函数调用B函数,B函数再次调用A函数。

想要让某段代码重复/循环执行,有两种解决方案:

1、while、for循环;

2、函数递归调用,本质就是循环。

核心规则:递归必须设置终止条件,禁止无限递归,否则会触发程序报错。Python默认递归深度限制约1000层,可手动修改。

# 直接递归(无限递归,报错示例,禁止使用)
# def f1():
#     print("111")
#     f1()
# f1()

# 间接递归(无限递归,报错示例,禁止使用)
# def f1():
#     print(111)
#     f2()
# def f2():
#     print(6666)
#     f1()
# f1()

# 查看/修改递归深度限制
import sys
print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)
print(sys.getrecursionlimit())

3.2 规范递归:回溯与递推

需要强调的是,递归调用不应该无限制地调用下去,必须在满足某种条件下结束递归调用。

以终止节点作为分水岭,函数递归调用可以分为两个阶段:

1、回溯:层层向下递归调用,直到触发终止条件;

2、递推:触发终止条件后,层层向上返回结果,最终得到最终值。

# 基础规范递归示例
def f1(n):
    # 终止条件
    if n == 10:
        return
    print(n)
    n += 1
    f1(n)

f1(0)

# 经典年龄递归案例
# 逻辑:age(1)=18,age(n)=age(n-1)+10
def age(n):
    if n == 1:
        return 18
    return age(n-1) + 10

res = age(5)
print(res)

3.3 递归实战:多层列表遍历

利用递归遍历多层嵌套列表,逐层拆解列表,打印所有非列表元素。

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

def f1(nums_list):
    print(nums_list)
    for item in nums_list:
        # 判断元素是否为列表,是则继续递归遍历
        if type(item) is list:
            f1(item)
        # 非列表元素直接打印
        else:
            print(item)

f1(l)

四、算法基础:二分查找法

算法是高效解决问题的方法,二分法是经典的有序序列查找算法。

需求:有一个按照从小到大顺序排列的数字列表,需要从该数字列表中找到我们想要的一个数字。

4.1 普通遍历方案(低效)

逐个遍历比对,数据量大时效率极低。

nums = [-5, 3, 7, 19, 23, 45, 63, 67, 103]
find_num = 99
for num in nums:
    if num == find_num:
        print('find it')
        break

4.2 递归二分法(高效)

核心逻辑:每次取列表中间值,对比目标数,舍弃一半无效区间,递归查找剩余区间,列表为空则判定不存在。

nums = [-5, 3, 7, 19, 23, 45, 63, 67, 103]

def search(find_num,nums_list):
    print(nums_list)
    # 终止条件:列表为空,查找失败
    if len(nums_list) == 0:
        print("not exists")
        return
    # 取中间索引与中间值
    mid_index = len(nums_list) // 2
    mid_val = nums_list[mid_index]
    # 目标值大于中间值,查找右半区间
    if find_num > mid_val:
        search(find_num,nums_list[mid_index+1:])
    # 目标值小于中间值,查找左半区间
    elif find_num < mid_val:
        search(find_num, nums_list[:mid_index])
    # 匹配成功
    else:
        print('find it')

search(68,nums)

五、编程思想范式

5.1 面向过程编程思想

核心是“过程”二字,过程就是流程、就是解决问题的步骤:先干什么、再干什么、后干什么。基于该思想写程序就好比是在设计一条流水线。

优点:复杂问题流程化、进而简单化

缺点:牵一发而动全身,扩展性差

面向过程编程思想的场景分析:

1、不是所有场景都需要频繁更迭,比如编写脚本;

2、即便是一个软件要频繁更迭,也并不代表该软件的所有部分都要更迭,软件整体的框架通常不会动,所以说程序的框架整体通常都是过程式。

六、函数进阶:匿名函数与高阶函数

6.1 有名函数与匿名函数

def定义的函数都是有名字的函数,函数名对应函数的内存地址,可重复调用。

# def定义有名函数,f1指向函数内存地址
def f1(x,y,z):
    print(x,y,z)

print(f1)
f1(1,2,3)

匿名函数通过lambda定义,无函数名,引用计数为0,使用一次就释放,适合临时使用一次的场景,通常与其他函数配合使用,作为其他函数的补充功能临时用一次。

语法:lambda 参数: 返回值表达式

# 匿名函数语法
lambda x,y,z: x + y + z

# 上述匿名函数的功能等同于下面的有名函数
# def func(x,y,z):
#     return x + y + z

# 匿名函数调用方式1:立即调用
res1 = (lambda x,y,z: x + y + z)(1,2,3)
print(res1)

# 匿名函数调用方式2:绑定变量(不建议,违背匿名初衷)
f = lambda x,y,z: x + y + z
print(f)
res2 = f(1,2,3)
print(res2)

6.2 匿名函数配合高阶函数实战

匿名函数核心用途:配合max、min、sorted、map、filter、reduce等高阶函数,临时提供逻辑规则。

储备知识:max基础用法

res = max([11,33,22,77,66])
print(res)

# 迭代取出    比较的值
# 11          11
# 33          33
# 22          22
# 77          77
# 66          66
# 最终返回77

实现需求:找出薪资最高的那个人的人名

salaries = {
    'egon': 3000,
    'tom': 7000,
    'lili': 10000,
    'jack': 2000
}

# 直接max字典,默认比较的是key的大小
# res = max(salaries)
# print(res)

# 迭代取出    比较的值
# egon        egon
# tom         tom
# lili        lili
# jack        jack
# 最终返回tom(按字符串排序)

# 通过key参数指定比较依据,配合匿名函数
res = max(salaries,key=lambda k:salaries[k])
res = min(salaries,key=lambda k:salaries[k])
res = sorted(salaries,key=lambda k:salaries[k])
res = sorted(salaries,key=lambda k:salaries[k],reverse=True)
print(res)

6.3 三大高阶函数详解

6.3.1 map映射函数(了解)

功能:遍历可迭代对象,对每个元素执行指定逻辑,返回新迭代器,用于批量处理数据。

l = ["egon","tom","jack"]

# 生成器表达式写法
# res = (name+"_dsb" for name in l)
# print(list(res))

# map写法
res = map(lambda name:name + "_dsb",l)
print(res)
print(list(res))

6.3.2 filter过滤函数(了解)

功能:根据条件筛选可迭代对象元素,保留条件成立的元素。

l = ["egon","tom_sb","jack_sb"]

# 生成器表达式写法
# res = (name for name in l if name.endswith('sb'))
# print(list(res))

# filter写法
res = filter(lambda name:name.endswith("sb"),l)
print(res)
print(list(res))

6.3.3 reduce累积函数(了解)

功能:对可迭代对象元素进行累积运算,两两迭代计算,最终返回单个值,需手动导入functools模块。

from functools import reduce

# 数值累加,带初始值
res = reduce(lambda x,y:x+y,[1,2,3],100)

# 字符串拼接,带初始值
res = reduce(lambda x,y:x+y,["aaa","bbb","ccc"],"--->")

print(res)

七、函数注解与常用内置方法

7.1 函数参数注解

用于标注参数、返回值的数据类型,仅做提示,不强制校验,提升代码可读性。可通过__annotations__查看所有注解信息。

# 自定义描述注解
def register(name: "必须传入一个字符串类型", age: "传整型", hobbies: "传元组") -> "返回值是整型":
    print(name)
    print(age)
    print(hobbies)
    return 123

# 标准类型注解
def register(name: str, age: int, hobbies: tuple) -> int:
    print(name)
    print(age)
    print(hobbies)
    return 123

# 查看注解
print(register.__annotations__)

7.2 常用内置函数大全

需掌握的核心内置函数:

# 字符与ASCII数字互转
print(chr(65))  # 参照ASCII表把数字转换字符
print(ord("A"))  # 参照ASCII表把字符转换数字

# 查看对象可调用的所有属性/方法
import time
print(dir(time))  # 查看可以.调用出的所有名字:time.名字

def f1():
    print('...')
print(dir(f1))

# 整除取商和余数
res = divmod(10,3)
print(res)

# 枚举遍历,同时获取索引和值
for i,v in enumerate([111,222,333]):
    print(i,v)

# 字符串转Python可执行对象
x = "[1,2,3]"
res = eval(x)
print(res,type(res))

res = eval("print('hello')")
print(res)

# 反转序列
l = [1, 22, 33, "a"]
new_l = reversed(l)
print(new_l)
print(list(new_l))

# 四舍五入
print(round(3.6))
print(round(3.4))

# 拉链配对,以最短序列为准
m = "abcdef"
n = [11,22,33]
res = zip(m,n)
print(res)
print(dict(res))

# 动态导入模块
m = __import__("time")
print(m.time())

了解类内置函数:

# 绝对值
print(abs(-1))

# 全部为真/任意为真
res = all([1, 2.3, "a", [1, 2, 3]])
res = all([1, 2.3, "", [1, 2, 3]])
print(res)
print(all([]))  # 可迭代对象没有包含任何值,all的结果为True

res = any([0, None, "123", []])
print(res)
print(any([]))    # 可迭代对象没有包含任何值,any的结果为False

# 进制转换
print(bin(11))  # 二进制 0b1011
print(oct(11))  # 八进制 0o13
print(hex(11))  # 十六进制 0xb

# 判断对象是否可调用
def f1():
    print(111)

print(callable(f1))

# 可变集合与不可变集合
s1 = set({1,2,3})
s1.add(4)
print(s1)

s2 = frozenset({1,2,3})  # 不可变集合

# 全局与局部变量字典
x=111
y=222
print("站在全局===>",globals())

def f1():
    m = 6666
    n = 777
    print("站在局部===>",globals())
    print("站在局部===>",locals())

f1()

# 哈希运算
res = hash("1111")
print(res)

# 幂运算取余
res = pow(10,2,3)  # 10 ** 2 % 3
print(res)

# 切片对象,复用切片规则
l = [11,22,33,44,55,66,77]
s = slice(1,5,2)
res = l[s]
print(res)

# 获取对象属性字典
print(vars())

八、面向对象基础预备知识

8.1 内置工厂函数

所有基础数据类型本质都是类,通过类实例化得到对象,这些类统称为工厂函数。

包含:int、float、str、list、tuple、dict、set、bool、bytes、complex

8.2 面向对象核心内置属性与方法

为后续面向对象编程的核心预备知识点,所有对象、类均可调用:

  • 装饰器与属性控制:classmethod、staticmethod、property

  • 属性操作:delattr(删除属性)、hasattr(判断是否有属性)、setattr(设置属性)、getattr(获取属性)

  • 代码执行:exec

  • 类型判断:isinstance、issubclass

  • 核心基类:object(所有类的顶层父类)、super(子类调用父类方法)

posted @ 2026-07-16 21:21  cuckooyang  阅读(9)  评论(0)    收藏  举报