按顺序对要上传的文件列表进行排序

Sorting a list of files to be uploaded in order

我的目标是 python 使用 telegram-upload 按升序将文件从设置的目录上传到 telegram。我的脚本似乎无法按顺序上传。它以随机顺序上传文件。我使用 sorted 函数无济于事。查看我的脚本,您可以看到我尝试过的一些内容(已评论)。我有一个 sorted 的设置,可以按顺序列出文件,但是在尝试上传时,我无法重新转换我创建并排序回字符串的列表,因此 subprocess 可以读取参数。

这是脚本:

import os
import subprocess
import time
#import shutil

Number_Of_Files = 0
#PATH = r'C:\Users\myuser\Downloads' 
PATH = '/home/pi/Public/'

for root, subFolder, files in os.walk(PATH):
    for item in files:
        #Number_Of_Files=Number_Of_Files+1
        fileNamePath = os.path.join(root, item)
        #sorted = sorted(fileNamePath)
        #subprocess.run(['telegram-upload', '-f', 'my_channel', str(sorted)])
        subprocess.run(['telegram-upload', '-f', 'my_channel', str(fileNamePath)])
        #os.remove(fileNamePath)
        print(fileNamePath)
        #time.sleep(60)
    #else:
        #print(Number_Of_Files)

sorted不行到位。如果要将更改传播回 os.walksubFolder 参数 必须 就地排序。如果你想直接使用 files ,你也需要就地排序。否则,您需要使用排序版本:

for root, subFolder, files in os.walk(PATH):
    files.sort()  # This sorts in-place
    subFolder.sort() # If you want sorted directories
    for item in files:
        fileNamePath = os.path.join(root, item)
        subprocess.run(['telegram-upload', '-f', 'my_channel', fileNamePath])

如果您不想就地对两个列表进行排序,您可以这样写:

for root, subFolder, files in os.walk(PATH):
    subFolder[:] = sorted(subFolder)  # creates a new list and assigns back to the original
    for item in sorted(files):
        fileNamePath = os.path.join(root, item)
        subprocess.run(['telegram-upload', '-f', 'my_channel', fileNamePath])

循环中的 运行 sorted 毫无意义。由于 sorted 每次都会创建一个新列表,并且循环遍历原始 files 列表,因此您对 sorted 的调用无效。您通常希望在循环序列之前应用排序,如上所示。

使用 pathlib and sorted:

可以大大简化整个循环
import subprocess
from pathlib import Path

p=Path('/home/pi/Public/')

for fn in sorted((x for x in p.glob('**/*') if x.is_file())):
    print(fn)
    # subprocess.run(['telegram-upload', '-f', 'my_channel', str(fn)])

glob('**/*') 是一个递归 glob,与使用 os.walk 等效,但更易于管理。 (x for x in p.glob('**/*') if x.is_file()) 是一种理解,只有returns 个文件,而不是目录和文件。排序的结果就可以了...

鉴于此文件夹结构:

.
├── A
│   ├── b.txt
│   ├── d.txt
│   └── y.doc
└── B
    ├── a.txt
    ├── c.txt
    └── x.doc

sorted((x for x in p.glob('**/*') if x.is_file()) returns 文件顺序:

./A/b.txt
./A/d.txt
./A/y.doc
./B/a.txt
./B/c.txt
./B/x.doc

如果您将排序理解更改为 sorted((x for x in p.glob('**/*') if x.is_file()), key=lambda x: x.name),那么您将仅按文件名对同一棵树进行排序:

./B/a.txt
./A/b.txt
./B/c.txt
./A/d.txt
./B/x.doc
./A/y.doc

或先按后缀排序,然后按 sorted((x for x in p.glob('**/*') if x.is_file()), key=lambda x: (x.suffix, x.name)) 命名:

./B/x.doc
./A/y.doc
./B/a.txt
./A/b.txt
./B/c.txt
./A/d.txt

使用相同的方法,您可以按创建时间、目录名称、扩展名等排序...