You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ZipFile.infolist()返回顺序与压缩包实际文件顺序不符的解决办法咨询

ZipFile.infolist()返回顺序与压缩包实际文件顺序不符的解决办法咨询

问题描述

我最近在实现一个功能:提取压缩包内的文件,并将它们重命名为从1到n的序列(保留原文件后缀)。但遇到了一个头疼的问题——当压缩包内的原文件名本身是按1、2、3...n命名时,ZipFile.infolist()返回的文件顺序完全不符合预期!

我最初写的代码是这样的:

from zipfile import ZipFile

with ZipFile(file) as zf:
    for i, file_info in enumerate(zf.infolist(), 1):
        # 提取原文件后缀并重新命名
        ext = file_info.filename.split(".")[-1]
        file_info.filename = f'{i}.{ext}'
        zf.extract(file_info, file_path)

结果调试时发现,压缩包里的文件本来是按1、2、3、4...n的顺序排列,但infolist()返回的ZipInfo列表却是按字符串字典序排序的——也就是1、10、11、12...2、3、4...这种顺序,直接导致我重命名后的文件顺序完全错乱了。

我想到过一个临时方案:让压缩包里的原文件名改成01、02、03这种带前导零的格式,但这个方案太依赖原始文件的命名规范,不够通用可靠。

解决方案

这个问题的根源在于:ZipFile.infolist()返回的顺序是文件在压缩包内部存储的顺序,而很多压缩工具(比如Windows默认的压缩功能)在添加数字命名的文件时,会按字符串字典序来添加,而非我们直观的数字大小顺序。所以我们需要手动对infolist()的结果进行排序,按照文件名的数字大小重新排列。

这里分两种常见场景给出解决代码:

场景1:文件名是纯数字+后缀(比如1.jpg、2.png)

直接提取文件名中的数字部分转成整数,以此作为排序依据:

from zipfile import ZipFile

def extract_and_rename(file, file_path):
    with ZipFile(file) as zf:
        # 按文件名的数字大小排序ZipInfo列表
        sorted_files = sorted(zf.infolist(), key=lambda x: int(x.filename.split(".")[0]))
        for i, file_info in enumerate(sorted_files, 1):
            ext = file_info.filename.split(".")[-1]
            file_info.filename = f'{i}.{ext}'
            zf.extract(file_info, file_path)

场景2:文件名包含其他字符但核心是数字(比如img_1.jpg、doc_2.pdf)

用正则表达式提取文件名中的数字部分,再进行排序:

import re
from zipfile import ZipFile

def extract_and_rename(file, file_path):
    with ZipFile(file) as zf:
        def get_file_number(file_info):
            # 匹配文件名中的连续数字
            match = re.search(r'\d+', file_info.filename)
            return int(match.group()) if match else 0  # 无数字的文件排到最后
        # 按提取到的数字大小排序
        sorted_files = sorted(zf.infolist(), key=get_file_number)
        for i, file_info in enumerate(sorted_files, 1):
            ext = file_info.filename.split(".")[-1]
            file_info.filename = f'{i}.{ext}'
            zf.extract(file_info, file_path)

补充说明

  • 如果你能控制压缩包的生成过程,也可以在打包时确保文件是按数字大小顺序添加的,但这种方式远不如手动排序灵活通用。
  • 不同压缩工具的文件存储逻辑可能有差异,但手动按数字排序的方案能覆盖绝大多数场景。

备注:内容来源于stack exchange,提问作者Murad Rustemzade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 12:08:13