Python——常见函数总结


chain()

  • chain()itertools 模块提供的一个非常实用的函数,它能够把多个可迭代对象连接起来,形成一个连续的迭代器

  • 基本用法为:

    1
    2
    from itertools import chain
    chain(*iterables) # 参数是多个可迭代对象(注意是展开形式)
  • 链接多个可迭代对象,可以是不同对象,对象内部的元素也可以是不同类型

    1
    2
    3
    4
    5
    6
    7
    8
    from itertools import chain

    set1 = {1, '2'}
    set2 = {3, 4}
    list1 = [5, 6]

    combined = list(chain(set1, set2, list1))
    print(combined) # 输出:[1, '2', 3, 4, 5, 6](集合元素顺序可能不同)
  • 特别说明,chain() 对可迭代对象是依次访问的,只有迭代访问完前面一个采集继续访问另一个


zip() 函数

  • zip 函数输入长度不一致时,不会报错,会适配最短长度
  • 示例:
    1
    2
    3
    4
    5
    6
    for a, b in zip([1,2,3],[1,4,4,5,4,5,6,7]):
    print(a, b)

    # 1 1
    # 2 4
    # 3 4

for…else 语句

  • 在 Python 中,for...else 是一种特殊的流程控制结构,for...else 的核心是通过 else 子句判断循环是否“自然完成”,而非被 break 强制终止,这在需要验证“遍历完整性”的场景中非常实用

  • 其基本语法为:

    1
    2
    3
    4
    for 变量 in 可迭代对象:
    循环体(当迭代继续时执行)
    else:
    else子句(当循环正常结束时执行)
  • 核心逻为:

    • else 子句的执行条件 :当 for 循环完整遍历了所有元素(即没有通过 break 语句提前退出循环),则循环结束后会执行 else 中的代码
    • else 子句不执行的情况 :如果循环中遇到 break 语句并跳出循环(提前终止),则 else 子句不会执行
  • 示例 1:循环正常结束(执行 else)

    1
    2
    3
    4
    5
    6
    7
    8
    for i in range(3):
    print(i)
    else:
    print("循环正常结束,执行 else") # 循环完整遍历了 `range(3)` 的所有元素(0、1、2),没有 `break`,因此 `else` 被执行
    # 0
    # 1
    # 2
    # 循环正常结束,执行 else
  • 示例 2:循环被 break 终止(不执行 else)

    1
    2
    3
    4
    5
    6
    7
    8
    for i in range(3):
    print(i)
    if i == 1:
    break # 当i=1时提前退出循环
    else:
    print("循环正常结束,执行 else") # 循环在 `i=1` 时通过 `break` 提前终止,因此 `else` 子句未执行
    # 0
    # 1
  • 典型应用场景:for...else 常用于判断“是否在循环中找到目标” ,例如在列表中查找元素:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    target = 5
    nums = [1, 3, 4, 6]

    for num in nums:
    if num == target:
    print(f"找到目标:{target}")
    break
    else:
    # 若循环完整执行(未触发break),说明未找到目标
    print(f"未找到目标:{target}") # 由于 `nums` 中没有 5,循环完整遍历后执行 `else`,提示“未找到目标”

    # 未找到目标:5

dict 特殊初始化逻辑

  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    default_config = { # 默认值定义
    "pass_score": 60,
    "check_mode": "all",
    "time_limit": 30
    }

    custom_config = {
    "pass_score": 75, # 覆盖默认:及格线提高到75分
    "need_detail": True # 新增:需要详细报告
    }

    # 配置合并,第一个是默认配置,第二个是新增或修改配置
    final_config = {**default_config, **custom_config}

    print(f"最终配置:{final_config}")

    # 最终配置:{'pass_score': 75, 'check_mode': 'all', 'time_limit': 30, 'need_detail': True}
  • 注:Python 3.9+ 还支持更简洁的 | 字典合并运算符(效果完全一致):

    1
    grader_params = grader_config.defaults | grader_dict
  • 运行原代码后,grader_params 的结果的是:

    1
    2
    3
    4
    5
    6
    {
    "score_threshold": 70, # 自定义覆盖了默认
    "check_type": "full", # 保留默认(无自定义冲突)
    "timeout": 30, # 保留默认
    "check_detail": True # 新增自定义配置
    }

string 的 rindexrfind 函数用法

  • rindex()rfind() 是字符串(str)的内置方法,核心作用是从字符串右侧(末尾)开始查找指定子串的最后一次出现位置 ,返回其索引值

    • 两者用法高度相似,仅在“子串未找到”时的行为不同
      • rfind():未找到返回 -1
      • rindex():未找到抛出 ValueError 异常
    • 两者返回子串都是在原字符串中最后一次出现的起始索引(索引从 0 开始)
  • 完整语法

    1
    2
    3
    4
    5
    # rfind():未找到返回 -1
    str.rfind(sub, start=0, end=len(str))

    # rindex():未找到抛出 ValueError 异常
    str.rindex(sub, start=0, end=len(str))
    • sub:必需参数,要查找的子串(可以是单个字符、多个字符的字符串)
    • start:可选参数,查找的起始索引(从左往右的索引,默认 0,即从字符串开头开始限定查找范围)
    • end:可选参数,查找的结束索引(不包含 end 本身,默认 len(str),即到字符串末尾结束)
  • 选择建议:如果不确定子串是否存在,优先用 rfind()(避免异常);如果明确子串一定存在,用 rindex()(逻辑更简洁)

使用示例

  • 基础用法(无 start/end 参数):从字符串末尾开始查找子串的最后一次出现位置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    s = "hello world, hello python"

    # 查找 "hello" 的最后一次出现
    print(s.rfind("hello")) # 输出 13(第二个 "hello" 的起始索引)
    print(s.rindex("hello")) # 输出 13

    # 查找单个字符 "o" 的最后一次出现
    print(s.rfind("o")) # 输出 18("python" 中的 "o")
    print(s.rindex("o")) # 输出 18

    # 查找不存在的子串
    print(s.rfind("java")) # 输出 -1(不报错)
    # print(s.rindex("java")) # 抛出 ValueError: substring not found
  • 指定 start/end 参数(限定查找范围):startend 限定“从原字符串的 [start, end) 区间内,从右往左查找”:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    s = "abcdeabcde"  # 索引 0-9

    # 限定查找范围:start=2,end=8(即子字符串 "cdeabc",索引 2-7)
    # 从该区间右侧开始找 "abc",最后一次出现是索引 5
    print(s.rfind("abc", 2, 8)) # 输出 5
    print(s.rindex("abc", 2, 8)) # 输出 5

    # 限定范围:start=0,end=5(子字符串 "abcde")
    # 该区间内 "abc" 只在索引 0 出现,从右找也是 0
    print(s.rfind("abc", 0, 5)) # 输出 0
  • 查找空字符串(特殊情况):如果 sub 是空字符串 "",两者都会返回 end - 1(因为空字符串在任何位置都存在,最后一次位置是 end 前一个索引):

    1
    2
    3
    s = "test"
    print(s.rfind("")) # 新版本输出4,3.9前的旧版本输出 3,
    print(s.rindex("", 0, 2)) # 新版本输出2,3.9前的旧版本输出 1

附录:与 index()/find() 的对比

  • find() / index():从左侧开始查找子串的第一次出现位置(未找到时 find 返回 -1,index 抛异常)
  • rfind() / rindex():从右侧开始查找子串的最后一次出现位置(未找到时行为同上)
  • 示例对比:
    1
    2
    3
    4
    5
    s = "abacada"
    print(s.find("a")) # 0(左侧第一次)
    print(s.rfind("a")) # 6(右侧第一次,即最后一次)
    print(s.index("a")) # 0
    print(s.rindex("a")) # 6